Skip to content

Commit efe577a

Browse files
raygdevmarktnoonanryanthemanuelmschilejennifer-shehane
authored
feat: Passing --browser flag alone will launch after test selection (#28538)
* Add localSettings field to OpenBrowser query * Add wasBrowserSetInCLI as OpenBrowserList prop * Emit launch on mount if --browser was passed * Add entry to cli changelog * Correct typo in changelog * Add link to issue addressed * Add pull request title * Check if browser is already open before launch * Moved features section to top of file * Add reference to PR in changelog * Correct unintended completion * Add features to top of changelog * Change prop name for convention * Add isValidBrowser checkes whether a cliBrowser is valid or not and returns a boolean * Add isValidBrowser to schema * Use isValid browser creates a function launchIfBrowserSetInCli that will launch the browser if a valid browser flag was passed to the cli * Add to changelog.md * Add global launch count to keep track project launch * Make global count available to the launchPad * Add description for globalLaunchCount * Add globalCounnt to schema * Remove unused import and remove unused prop * Use launch function * Import document and use query * Add to changelog * Add to existing features section * Add to changelog * Update changelog.md * Add setter for launchCount and add tests * Update changelog * Remove extra bugfix title * Update changelog * Update changelog * Update changelog * Update changelog * Update Changelog * Update changelog * Update Changelog * Update changelog * Fix changelog for line break error * Update changelog * Refactor to create single field for launching browser * Update schema * Refactor function to make use of single field * Change launch count in beforeEach hook instead * Clean up await in function * Update changelog * Add additional optional chaining for resiliency * Use more precise browser launching query to fix silent bug * Assert that launchProject hasn't been called when browser not found * Update changelog * Update cli/CHANGELOG.md --------- Co-authored-by: Mark Noonan <mark@cypress.io> Co-authored-by: Ryan Manuel <ryanm@cypress.io> Co-authored-by: Matt Schile <mschile@cypress.io> Co-authored-by: Jennifer Shehane <shehane.jennifer@gmail.com> Co-authored-by: Jennifer Shehane <jennifer@cypress.io>
1 parent 5a6b8c4 commit efe577a

File tree

7 files changed

+97
-3
lines changed

7 files changed

+97
-3
lines changed

cli/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ _Released 8/27/2024 (PENDING)_
1515
- `.type({upArrow})` and `.type({downArrow})` now also works for date, month, week, time, datetime-local and range input types. Addresses [#29665](https://github.com/cypress-io/cypress/issues/29665).
1616
- Added a `CYPRESS_SKIP_VERIFY` flag to enable suppressing Cypress verification checks. Addresses [#22243](https://github.com/cypress-io/cypress/issues/22243).
1717
- Updated the protocol to allow making Cloud API requests. Addressed in [#30066](https://github.com/cypress-io/cypress/pull/30066).
18+
- Passing the browser without the testing type (i.e. `cypress open --browser <browser-name-or-path>`) will now directly launch the browser after the testing type is selected. Addresses [#22003](https://github.com/cypress-io/cypress/issues/22003). Addressed in [#28538](https://github.com/cypress-io/cypress/pull/28538).
1819

1920
**Bugfixes:**
2021

packages/data-context/src/actions/ProjectActions.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,13 @@ type SetForceReconfigureProjectByTestingType = {
8989
const debug = debugLib('cypress:data-context:ProjectActions')
9090

9191
export class ProjectActions {
92+
/**
93+
* @var globalLaunchCount
94+
* Used as a read-only in the launchpad to ensure
95+
* that launchProject is only called once if
96+
* the --browser flag is passed alone.
97+
*/
98+
private globalLaunchCount = 0
9299
constructor (private ctx: DataContext) {}
93100

94101
private get api () {
@@ -127,6 +134,14 @@ export class ProjectActions {
127134
})
128135
}
129136

137+
get launchCount () {
138+
return this.globalLaunchCount
139+
}
140+
141+
set launchCount (count) {
142+
this.globalLaunchCount = count
143+
}
144+
130145
openDirectoryInIDE (projectPath: string) {
131146
this.ctx.debug(`opening ${projectPath} in ${this.ctx.coreData.localSettings.preferences.preferredEditorBinary}`)
132147

@@ -284,6 +299,7 @@ export class ProjectActions {
284299
}
285300

286301
await this.api.launchProject(browser, activeSpec ?? emptySpec, options)
302+
this.globalLaunchCount++
287303

288304
return
289305
}

packages/graphql/schemas/schema.graphql

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1444,6 +1444,11 @@ type LocalSettingsPreferences {
14441444
proxyBypass: String
14451445
proxyServer: String
14461446
reporterWidth: Int
1447+
1448+
"""
1449+
Determine if the browser should launch when the browser flag is passed alone
1450+
"""
1451+
shouldLaunchBrowserFromOpenBrowser: Boolean
14471452
specListWidth: Int
14481453
wasBrowserSetInCLI: Boolean
14491454
}

packages/graphql/src/schemaTypes/objectTypes/gql-LocalSettings.ts

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,27 @@ export const LocalSettingsPreferences = objectType({
3333
},
3434
})
3535

36+
t.boolean('shouldLaunchBrowserFromOpenBrowser', {
37+
description: 'Determine if the browser should launch when the browser flag is passed alone',
38+
resolve: async (_source, _args, ctx) => {
39+
try {
40+
const cliBrowser = ctx.coreData.cliBrowser
41+
42+
if (!cliBrowser) {
43+
return false
44+
}
45+
46+
const browser = await ctx._apis.browserApi.ensureAndGetByNameOrPath(cliBrowser)
47+
const shouldLaunch = Boolean(browser) && (ctx.actions.project.launchCount === 0)
48+
49+
return shouldLaunch
50+
} catch (e) {
51+
// if error is thrown, browser doesn't exist
52+
return false
53+
}
54+
},
55+
})
56+
3657
t.boolean('debugSlideshowComplete')
3758
t.boolean('desktopNotificationsEnabled')
3859
t.dateTime('dismissNotificationBannerUntil')

packages/launchpad/cypress/e2e/choose-a-browser.cy.ts

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@ import type { FoundBrowser } from '@packages/types'
33
describe('Choose a browser page', () => {
44
beforeEach(() => {
55
cy.scaffoldProject('launchpad')
6+
cy.withCtx((ctx, _) => {
7+
ctx.actions.project.launchCount = 0
8+
})
69
})
710

811
describe('System Browsers Detected', () => {
@@ -14,6 +17,24 @@ describe('Choose a browser page', () => {
1417
})
1518
})
1619

20+
it('launches when --browser is passed alone through the command line', () => {
21+
cy.withCtx((ctx, o) => {
22+
o.sinon.stub(ctx._apis.projectApi, 'launchProject').resolves()
23+
})
24+
25+
cy.openProject('launchpad', ['--browser', 'edge'])
26+
cy.visitLaunchpad()
27+
28+
cy.skipWelcome()
29+
cy.get('[data-cy=card]').then(($buttons) => {
30+
$buttons[0].click()
31+
})
32+
33+
cy.withRetryableCtx((ctx, o) => {
34+
expect(ctx._apis.projectApi.launchProject).to.be.calledOnce
35+
})
36+
})
37+
1738
it('preselects browser that is provided through the command line', () => {
1839
cy.withCtx((ctx, o) => {
1940
// stub launching project since we have `--browser --testingType --project` here
@@ -37,6 +58,10 @@ describe('Choose a browser page', () => {
3758
})
3859

3960
it('shows warning when launched with --browser name that cannot be matched to found browsers', () => {
61+
cy.withCtx((ctx, o) => {
62+
o.sinon.stub(ctx._apis.projectApi, 'launchProject').resolves()
63+
})
64+
4065
cy.openProject('launchpad', ['--e2e', '--browser', 'doesNotExist'])
4166
cy.visitLaunchpad()
4267
cy.skipWelcome()
@@ -55,6 +80,9 @@ describe('Choose a browser page', () => {
5580
// Ensure warning can be dismissed
5681
cy.get('[data-cy="alert-suffix-icon"]').click()
5782
cy.get('[data-cy="alert-header"]').should('not.exist')
83+
cy.withRetryableCtx((ctx, o) => {
84+
expect(ctx._apis.projectApi.launchProject).not.to.be.called
85+
})
5886
})
5987

6088
it('shows warning when launched with --browser path option that cannot be matched to found browsers', () => {

packages/launchpad/src/Main.vue

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,7 @@ fragment MainLaunchpadQueryData on Query {
132132
preferences {
133133
majorVersionWelcomeDismissed
134134
wasBrowserSetInCLI
135+
shouldLaunchBrowserFromOpenBrowser
135136
}
136137
}
137138
currentProject {
@@ -246,11 +247,11 @@ watch(
246247
247248
function handleClearLandingPage () {
248249
setMajorVersionWelcomeDismissed(MAJOR_VERSION_FOR_CONTENT)
249-
const wasBrowserSetInCLI = query.data?.value?.localSettings.preferences?.wasBrowserSetInCLI
250+
const shouldLaunchBrowser = query.data?.value?.localSettings?.preferences?.shouldLaunchBrowserFromOpenBrowser
250251
251252
const currentTestingType = currentProject.value?.currentTestingType
252253
253-
if (wasBrowserSetInCLI && currentTestingType) {
254+
if (shouldLaunchBrowser && currentTestingType) {
254255
launchProject.executeMutation({ testingType: currentTestingType })
255256
}
256257
}

packages/launchpad/src/setup/OpenBrowser.vue

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
import { useMutation, gql, useQuery } from '@urql/vue'
2323
import OpenBrowserList from './OpenBrowserList.vue'
2424
import WarningList from '../warning/WarningList.vue'
25-
import { OpenBrowserDocument, OpenBrowser_CloseBrowserDocument, OpenBrowser_ClearTestingTypeDocument, OpenBrowser_LaunchProjectDocument, OpenBrowser_FocusActiveBrowserWindowDocument, OpenBrowser_ResetLatestVersionTelemetryDocument } from '../generated/graphql'
25+
import { OpenBrowserDocument, OpenBrowser_CloseBrowserDocument, OpenBrowser_ClearTestingTypeDocument, OpenBrowser_LaunchProjectDocument, OpenBrowser_FocusActiveBrowserWindowDocument, OpenBrowser_ResetLatestVersionTelemetryDocument, OpenBrowser_LocalSettingsDocument } from '../generated/graphql'
2626
import LaunchpadHeader from './LaunchpadHeader.vue'
2727
import { useI18n } from '@cy/i18n'
2828
import { computed, ref, onMounted } from 'vue'
@@ -42,7 +42,18 @@ query OpenBrowser {
4242
}
4343
`
4444
45+
gql`
46+
query OpenBrowser_LocalSettings {
47+
localSettings {
48+
preferences {
49+
shouldLaunchBrowserFromOpenBrowser
50+
}
51+
}
52+
}
53+
`
54+
4555
const query = useQuery({ query: OpenBrowserDocument })
56+
const lsQuery = useQuery({ query: OpenBrowser_LocalSettingsDocument, requestPolicy: 'network-only' })
4657
4758
gql`
4859
mutation OpenBrowser_ClearTestingType {
@@ -106,6 +117,16 @@ const launch = async () => {
106117
}
107118
}
108119
120+
const launchIfBrowserSetInCli = async () => {
121+
const shouldLaunchBrowser = (await lsQuery).data.value?.localSettings?.preferences?.shouldLaunchBrowserFromOpenBrowser
122+
123+
if (shouldLaunchBrowser) {
124+
await launch()
125+
}
126+
127+
return
128+
}
129+
109130
const backFn = () => {
110131
clearCurrentTestingType.executeMutation({})
111132
}
@@ -126,6 +147,7 @@ const setFocusToActiveBrowserWindow = () => {
126147
127148
onMounted(() => {
128149
resetLatestVersionTelemetry.executeMutation({})
150+
launchIfBrowserSetInCli()
129151
})
130152
131153
</script>

0 commit comments

Comments
 (0)