From 56738ab7541258c9c32e5136701557e5d8d03458 Mon Sep 17 00:00:00 2001 From: Lauren Zugai Date: Fri, 20 Sep 2024 17:28:45 -0500 Subject: [PATCH] feat(pair/CAD): Implement signed-in '/connect_another_device' and '/pair' mods + redirects --- .../pages/connectAnotherDevice.ts | 7 +- .../tests/misc/recoveryKeyPromo.spec.ts | 7 +- .../syncForcePasswordChange.spec.ts | 4 +- .../react-conversion/oauthSignup.spec.ts | 2 +- .../signInConnectAnotherDevice.spec.ts | 9 +- .../signInRelyingParties.spec.ts | 2 +- .../tests/react-conversion/signinTotp.spec.ts | 2 +- .../tests/react-conversion/signup.spec.ts | 4 +- .../react-conversion/syncV3SignIn.spec.ts | 2 +- .../oauthResetPasswordSyncMobile.spec.ts | 2 +- .../tests/settings/fxaStatus.spec.ts | 5 +- .../tests/signin/connectAnotherDevice.spec.ts | 8 +- .../tests/syncV3/fxDesktopV3ForceAuth.spec.ts | 4 +- .../tests/syncV3/oauthSignIn.spec.ts | 2 +- .../tests/syncV3/settings.spec.ts | 2 +- .../tests/syncV3/signIn.spec.ts | 4 +- .../tests/syncV3/signinCached.spec.ts | 4 +- .../app/scripts/lib/constants.js | 1 + .../app/scripts/lib/user-agent.js | 15 + .../templates/connect_another_device.mustache | 33 +-- .../app/scripts/templates/pair/index.mustache | 121 ++++---- .../templates/pair/unsupported.mustache | 8 +- .../partial/unsupported-pair.mustache | 5 + .../scripts/views/connect_another_device.js | 14 + .../views/mixins/pairing-graphics-mixin.js | 17 -- .../app/scripts/views/pair/index.js | 17 +- .../app/scripts/views/pair/unsupported.js | 4 +- .../spec/views/connect_another_device.js | 259 ++---------------- .../views/mixins/pairing-graphics-mixin.js | 37 --- .../app/tests/spec/views/pair/index.js | 21 -- .../app/tests/spec/views/pair/unsupported.js | 5 + .../InlineRecoveryKeySetup/container.test.tsx | 2 +- .../Signin/SigninPushCode/container.test.tsx | 2 +- .../Signin/SigninTotpCode/index.test.tsx | 2 +- .../src/pages/Signin/index.test.tsx | 4 +- .../fxa-settings/src/pages/Signin/utils.ts | 2 +- 36 files changed, 172 insertions(+), 467 deletions(-) create mode 100755 packages/fxa-content-server/app/scripts/templates/partial/unsupported-pair.mustache diff --git a/packages/functional-tests/pages/connectAnotherDevice.ts b/packages/functional-tests/pages/connectAnotherDevice.ts index c1029cd1b3b..b901c162b3a 100644 --- a/packages/functional-tests/pages/connectAnotherDevice.ts +++ b/packages/functional-tests/pages/connectAnotherDevice.ts @@ -10,10 +10,11 @@ export class ConnectAnotherDevicePage extends BaseLayout { readonly selectors = { CONNECT_ANOTHER_DEVICE_HEADER: '#fxa-connect-another-device-header', CONNECT_ANOTHER_DEVICE_SIGNIN_BUTTON: 'form div a', - FXA_CONNECTED_HEADER: '#fxa-connected-heading', + FXA_CONNECTED_HEADER: '#cad-header', TEXT_INSTALL_FX_DESKTOP: '#install-mobile-firefox-desktop', SUCCESS: '.success', NOT_NOW: '#cad-not-now', + NOT_NOW_PAIR: '#choice-pair-not-now', }; get header() { @@ -49,4 +50,8 @@ export class ConnectAnotherDevicePage extends BaseLayout { async clickNotNow() { return this.page.locator(this.selectors.NOT_NOW).click(); } + + async clickNotNowPair() { + return this.page.locator(this.selectors.NOT_NOW_PAIR).click(); + } } diff --git a/packages/functional-tests/tests/misc/recoveryKeyPromo.spec.ts b/packages/functional-tests/tests/misc/recoveryKeyPromo.spec.ts index 45e5ed39d59..8d273488658 100644 --- a/packages/functional-tests/tests/misc/recoveryKeyPromo.spec.ts +++ b/packages/functional-tests/tests/misc/recoveryKeyPromo.spec.ts @@ -89,7 +89,7 @@ test.describe('recovery key promo', () => { await login.setCode(code); await login.clickSubmit(); - await expect(connectAnotherDevice.header).toBeVisible(); + await expect(connectAnotherDevice.fxaConnected).toBeEnabled(); }); test('not shown if user already has a recovery key', async ({ @@ -125,7 +125,7 @@ test.describe('recovery key promo', () => { await signin.fillOutEmailFirstForm(credentials.email); await signin.fillOutPasswordForm(credentials.password); - await expect(connectAnotherDevice.header).toBeVisible(); + await expect(connectAnotherDevice.fxaConnected).toBeVisible(); }); test('can setup recovery key inline after sign-in', async ({ @@ -266,6 +266,7 @@ test.describe('recovery key promo', () => { await inlineRecoveryKey.clickDoItLater(); // User taken to connect another device page + await page.waitForURL(/connect_another_device/); await expect(connectAnotherDevice.header).toBeVisible(); await connectAnotherDevice.startBrowsingButton.click(); @@ -283,7 +284,7 @@ test.describe('recovery key promo', () => { ); await signin.fillOutEmailFirstForm(credentials.email); await signin.fillOutPasswordForm(credentials.password); - await expect(connectAnotherDevice.header).toBeVisible(); + await expect(connectAnotherDevice.fxaConnected).toBeVisible(); }); }); }); diff --git a/packages/functional-tests/tests/postVerify/syncForcePasswordChange.spec.ts b/packages/functional-tests/tests/postVerify/syncForcePasswordChange.spec.ts index dbc1a356270..4d0b04b2de7 100644 --- a/packages/functional-tests/tests/postVerify/syncForcePasswordChange.spec.ts +++ b/packages/functional-tests/tests/postVerify/syncForcePasswordChange.spec.ts @@ -39,8 +39,8 @@ test.describe('severity-2 #smoke', () => { await postVerify.submit(); credentials.password = newPassword; - //Verify logged in on connect another device page - await expect(connectAnotherDevice.fxaConnected).toBeEnabled(); + // Verify logged in on connect another device page + await expect(connectAnotherDevice.header).toBeVisible(); }); }); }); diff --git a/packages/functional-tests/tests/react-conversion/oauthSignup.spec.ts b/packages/functional-tests/tests/react-conversion/oauthSignup.spec.ts index 6c8a03ded9b..b370f73e7da 100644 --- a/packages/functional-tests/tests/react-conversion/oauthSignup.spec.ts +++ b/packages/functional-tests/tests/react-conversion/oauthSignup.spec.ts @@ -148,7 +148,7 @@ test.describe('severity-1 #smoke', () => { const code = await target.emailClient.getVerifyShortCode(email); await confirmSignupCode.fillOutCodeForm(code); - await expect(page).toHaveURL(/connect_another_device/); + await expect(page).toHaveURL(/pair/); await signup.checkWebChannelMessage(FirefoxCommand.OAuthLogin); }); }); diff --git a/packages/functional-tests/tests/react-conversion/signInConnectAnotherDevice.spec.ts b/packages/functional-tests/tests/react-conversion/signInConnectAnotherDevice.spec.ts index b77fd4f0fdb..bc37e7d5d46 100644 --- a/packages/functional-tests/tests/react-conversion/signInConnectAnotherDevice.spec.ts +++ b/packages/functional-tests/tests/react-conversion/signInConnectAnotherDevice.spec.ts @@ -6,7 +6,7 @@ import { expect, test } from '../../lib/fixtures/standard'; test.describe('severity-2 #smoke', () => { test.describe('connect_another_device', () => { - test('react signin Fx Desktop, load /connect_another_device page', async ({ + test('react signin Fx Desktop, load /pair page', async ({ syncBrowserPages: { configPage, connectAnotherDevice, page, signin }, testAccountTracker, }) => { @@ -26,13 +26,8 @@ test.describe('severity-2 #smoke', () => { await signin.fillOutEmailFirstForm(credentials.email); await signin.fillOutPasswordForm(credentials.password); - await expect(page).toHaveURL(/connect_another_device/); + await expect(page).toHaveURL(/pair/); await expect(connectAnotherDevice.fxaConnected).toBeVisible(); - await expect( - connectAnotherDevice.connectAnotherDeviceButton - ).toBeVisible(); - await expect(connectAnotherDevice.signInButton).toBeHidden(); - await expect(connectAnotherDevice.success).toBeHidden(); }); }); }); diff --git a/packages/functional-tests/tests/react-conversion/signInRelyingParties.spec.ts b/packages/functional-tests/tests/react-conversion/signInRelyingParties.spec.ts index 8439dec2cd4..505efcb48b5 100644 --- a/packages/functional-tests/tests/react-conversion/signInRelyingParties.spec.ts +++ b/packages/functional-tests/tests/react-conversion/signInRelyingParties.spec.ts @@ -34,7 +34,7 @@ test.describe('severity-1 #smoke', () => { await signin.fillOutPasswordForm(credentials.password); await expect(connectAnotherDevice.fxaConnected).toBeEnabled(); - await connectAnotherDevice.startBrowsingButton.click(); + await connectAnotherDevice.clickNotNowPair(); await expect(page).toHaveURL(/settings/, { timeout: 1000 }); await settings.disconnectSync(credentials); diff --git a/packages/functional-tests/tests/react-conversion/signinTotp.spec.ts b/packages/functional-tests/tests/react-conversion/signinTotp.spec.ts index 6fafe95668b..300e92e6746 100644 --- a/packages/functional-tests/tests/react-conversion/signinTotp.spec.ts +++ b/packages/functional-tests/tests/react-conversion/signinTotp.spec.ts @@ -93,7 +93,7 @@ test.describe('severity-1 #smoke', () => { const code = await getCode(secret); await signin.fillOutAuthenticationForm(code); - await expect(page).toHaveURL(/connect_another_device/); + await expect(page).toHaveURL(/pair/); await expect(connectAnotherDevice.fxaConnected).toBeVisible(); diff --git a/packages/functional-tests/tests/react-conversion/signup.spec.ts b/packages/functional-tests/tests/react-conversion/signup.spec.ts index 2358d8a2e36..984694a768e 100644 --- a/packages/functional-tests/tests/react-conversion/signup.spec.ts +++ b/packages/functional-tests/tests/react-conversion/signup.spec.ts @@ -91,8 +91,8 @@ test.describe('severity-1 #smoke', () => { const code = await target.emailClient.getVerifyShortCode(email); await confirmSignupCode.fillOutCodeForm(code); - await expect(page).toHaveURL(/connect_another_device/); - await expect(page.getByText('You’re signed in to Firefox')).toBeVisible(); + await expect(page).toHaveURL(/pair/); + await expect(page.getByText('Signed in successfully')).toBeVisible(); }); }); }); diff --git a/packages/functional-tests/tests/react-conversion/syncV3SignIn.spec.ts b/packages/functional-tests/tests/react-conversion/syncV3SignIn.spec.ts index e757852c337..0979e8d89d1 100644 --- a/packages/functional-tests/tests/react-conversion/syncV3SignIn.spec.ts +++ b/packages/functional-tests/tests/react-conversion/syncV3SignIn.spec.ts @@ -52,6 +52,6 @@ test.describe('severity-2 #smoke', () => { await signinTokenCode.fillOutCodeForm(code); - await expect(page).toHaveURL(/connect_another_device/); + await expect(page).toHaveURL(/pair/); }); }); diff --git a/packages/functional-tests/tests/resetPassword/resetPasswordWithCode/oauthResetPasswordSyncMobile.spec.ts b/packages/functional-tests/tests/resetPassword/resetPasswordWithCode/oauthResetPasswordSyncMobile.spec.ts index b361365b151..534365386dc 100644 --- a/packages/functional-tests/tests/resetPassword/resetPasswordWithCode/oauthResetPasswordSyncMobile.spec.ts +++ b/packages/functional-tests/tests/resetPassword/resetPasswordWithCode/oauthResetPasswordSyncMobile.spec.ts @@ -58,7 +58,7 @@ test.describe('severity-1 #smoke', () => { // new passwowrd works await signin.fillOutPasswordForm(newPassword); - await expect(connectAnotherDevice.header).toBeVisible(); + await expect(connectAnotherDevice.fxaConnected).toBeVisible(); // update password for cleanup function credentials.password = newPassword; diff --git a/packages/functional-tests/tests/settings/fxaStatus.spec.ts b/packages/functional-tests/tests/settings/fxaStatus.spec.ts index 25db46539ad..8ce8f8efc72 100644 --- a/packages/functional-tests/tests/settings/fxaStatus.spec.ts +++ b/packages/functional-tests/tests/settings/fxaStatus.spec.ts @@ -23,7 +23,8 @@ test.describe('fxa_status web channel message in Settings', () => { `${target.contentServerUrl}/?context=fx_desktop_v3&service=sync` ); const credentials = await signInAccount(signin, testAccountTracker); - await expect(connectAnotherDevice.header).toBeVisible(); + await page.waitForURL(/pair/); + await expect(connectAnotherDevice.fxaConnected).toBeVisible(); await page.goto(target.contentServerUrl); await signin.useDifferentAccountLink.click(); @@ -45,7 +46,7 @@ test.describe('fxa_status web channel message in Settings', () => { `${target.contentServerUrl}/?context=fx_desktop_v3&service=sync` ); await signInAccount(signin, testAccountTracker); - await expect(connectAnotherDevice.header).toBeVisible(); + await expect(connectAnotherDevice.fxaConnected).toBeEnabled(); await page.goto(target.contentServerUrl); await signin.useDifferentAccountLink.click(); diff --git a/packages/functional-tests/tests/signin/connectAnotherDevice.spec.ts b/packages/functional-tests/tests/signin/connectAnotherDevice.spec.ts index e9af33ec018..2f902212372 100644 --- a/packages/functional-tests/tests/signin/connectAnotherDevice.spec.ts +++ b/packages/functional-tests/tests/signin/connectAnotherDevice.spec.ts @@ -19,14 +19,8 @@ test.describe('severity-2 #smoke', () => { await signin.fillOutEmailFirstForm(credentials.email); await signin.fillOutPasswordForm(credentials.password); - await page.waitForURL(/connect_another_device/); - + await expect(page).toHaveURL(/pair/); await expect(connectAnotherDevice.fxaConnected).toBeVisible(); - await expect( - connectAnotherDevice.connectAnotherDeviceButton - ).toBeVisible(); - await expect(connectAnotherDevice.signInButton).toBeHidden(); - await expect(connectAnotherDevice.success).toBeHidden(); }); }); }); diff --git a/packages/functional-tests/tests/syncV3/fxDesktopV3ForceAuth.spec.ts b/packages/functional-tests/tests/syncV3/fxDesktopV3ForceAuth.spec.ts index db022dab3e8..5a13db3b0b4 100644 --- a/packages/functional-tests/tests/syncV3/fxDesktopV3ForceAuth.spec.ts +++ b/packages/functional-tests/tests/syncV3/fxDesktopV3ForceAuth.spec.ts @@ -73,7 +73,7 @@ test.describe('severity-1 #smoke', () => { credentials.email ); await signinTokenCode.fillOutCodeForm(code); - await expect(page).toHaveURL(/connect_another_device/); + await expect(page).toHaveURL(/pair/); await expect(connectAnotherDevice.fxaConnected).toBeVisible(); await fxDesktopV3ForceAuth.checkWebChannelMessage(FirefoxCommand.Login); }); @@ -142,7 +142,7 @@ test.describe('severity-1 #smoke', () => { const code = await target.emailClient.getUnblockCode(credentials.email); await signinUnblock.fillOutCodeForm(code); - await expect(page).toHaveURL(/connect_another_device/); + await expect(page).toHaveURL(/pair/); await expect(connectAnotherDevice.fxaConnected).toBeVisible(); await fxDesktopV3ForceAuth.checkWebChannelMessage(FirefoxCommand.Login); diff --git a/packages/functional-tests/tests/syncV3/oauthSignIn.spec.ts b/packages/functional-tests/tests/syncV3/oauthSignIn.spec.ts index 09a894ae1d5..406102a8d86 100644 --- a/packages/functional-tests/tests/syncV3/oauthSignIn.spec.ts +++ b/packages/functional-tests/tests/syncV3/oauthSignIn.spec.ts @@ -25,7 +25,7 @@ test.describe('severity-1 #smoke', () => { ); await signin.fillOutEmailFirstForm(credentials.email); await signin.fillOutPasswordForm(credentials.password); - await expect(page).toHaveURL(/connect_another_device/); + await expect(page).toHaveURL(/pair/); await expect(connectAnotherDevice.fxaConnected).toBeVisible(); await relier.goto(); diff --git a/packages/functional-tests/tests/syncV3/settings.spec.ts b/packages/functional-tests/tests/syncV3/settings.spec.ts index 2d9059e5c1c..50ad014a43b 100644 --- a/packages/functional-tests/tests/syncV3/settings.spec.ts +++ b/packages/functional-tests/tests/syncV3/settings.spec.ts @@ -154,7 +154,7 @@ test.describe('severity-2 #smoke', () => { credentials.email ); await signinTokenCode.fillOutCodeForm(code); - await expect(page).toHaveURL(/connect_another_device/); + await expect(page).toHaveURL(/pair/); await settings.goto(); //Click Delete account diff --git a/packages/functional-tests/tests/syncV3/signIn.spec.ts b/packages/functional-tests/tests/syncV3/signIn.spec.ts index 579d6589b6f..e82a88123e8 100644 --- a/packages/functional-tests/tests/syncV3/signIn.spec.ts +++ b/packages/functional-tests/tests/syncV3/signIn.spec.ts @@ -222,8 +222,8 @@ test.describe('severity-2 #smoke', () => { await expect(connectAnotherDevice.fxaConnected).toBeVisible(); - //Delete blocked account, required before teardown - await connectAnotherDevice.startBrowsingButton.click(); + // Delete blocked account, required before teardown + await connectAnotherDevice.clickNotNowPair(); await settings.deleteAccountButton.click(); await deleteAccount.deleteAccount(credentials.password); diff --git a/packages/functional-tests/tests/syncV3/signinCached.spec.ts b/packages/functional-tests/tests/syncV3/signinCached.spec.ts index 8705784943f..7725a7c99dc 100644 --- a/packages/functional-tests/tests/syncV3/signinCached.spec.ts +++ b/packages/functional-tests/tests/syncV3/signinCached.spec.ts @@ -33,8 +33,8 @@ test.describe('severity-2 #smoke', () => { await expect(signin.passwordFormHeading).toBeVisible(); await expect(page.getByText(credentials.email)).toBeVisible(); await signin.fillOutPasswordForm(credentials.password); - await expect(page).toHaveURL(/connect_another_device/); - await connectAnotherDevice.clickNotNow(); + await expect(page).toHaveURL(/pair/); + await connectAnotherDevice.clickNotNowPair(); //Verify logged in on Settings page await expect(settings.settingsHeading).toBeVisible(); diff --git a/packages/fxa-content-server/app/scripts/lib/constants.js b/packages/fxa-content-server/app/scripts/lib/constants.js index 7f05b506b77..c54fedd0592 100644 --- a/packages/fxa-content-server/app/scripts/lib/constants.js +++ b/packages/fxa-content-server/app/scripts/lib/constants.js @@ -173,6 +173,7 @@ module.exports = { FIREFOX_SYNCED_TABS_ENTRYPOINT: 'synced-tabs', FIREFOX_TABS_SIDEBAR_ENTRYPOINT: 'tabs-sidebar', FIREFOX_FX_VIEW_ENTRYPOINT: 'fx-view', + FIREFOX_AVATAR_ENTRYPOINT: 'fxa_avatar_menu', // This is compared against all secondary email // records, both verified and unverified diff --git a/packages/fxa-content-server/app/scripts/lib/user-agent.js b/packages/fxa-content-server/app/scripts/lib/user-agent.js index 60310433a36..78524f23037 100644 --- a/packages/fxa-content-server/app/scripts/lib/user-agent.js +++ b/packages/fxa-content-server/app/scripts/lib/user-agent.js @@ -27,10 +27,25 @@ const UserAgent = function (userAgent) { return this.os.name === 'iOS' || this.isDesktopFirefoxOnIpad(); }, + /** + * Check if the device is iOS or Android. + * + * This does not work for latest iPad, see note above isDesktopFirefoxOnIpad. + * + * @returns {Boolean} + */ + isMobile() { + return this.isIos() || this.isAndroid(); + }, + /** * iPads using FF iOS 13+ send a desktop UA. * The OS shows as a Mac, but 'Firefox iOS' in the UA family. * + * NOTE, as of at least Sept 2024, this is no longer reliable. + * The UA for iPad Safari exactly matches the UA for iPad Firefox + * except for "Version" which is unreliable. + * * @returns {Boolean} */ isDesktopFirefoxOnIpad() { diff --git a/packages/fxa-content-server/app/scripts/templates/connect_another_device.mustache b/packages/fxa-content-server/app/scripts/templates/connect_another_device.mustache index 68ea7f9120b..78371f7446c 100644 --- a/packages/fxa-content-server/app/scripts/templates/connect_another_device.mustache +++ b/packages/fxa-content-server/app/scripts/templates/connect_another_device.mustache @@ -18,7 +18,7 @@ {{/isSignedIn}} {{/showSuccessMessage}}
- + {{#showSuccessMessage}} {{#isSignedIn}} {{#isFirefoxDesktop}} @@ -65,33 +65,10 @@ {{/isSignedIn}}

{{/isFirefoxDesktop}} - {{#isFirefoxIos}} - -

- {{#t}}Still adding devices? Sign in to Firefox on another device to complete set-up{{/t}} -

- {{/isFirefoxIos}} - {{#isOtherAndroid}} - -

- {{#t}}Sign in to Firefox for Android to complete set-up{{/t}} -

- {{/isOtherAndroid}} - {{#isOtherIos}} - -

- {{#t}}Sign in to Firefox for iOS to complete set-up{{/t}} -

- {{/isOtherIos}} - {{#isOther}} - -

- {{#isSignIn}} - {{#t}}Still adding devices?{{/t}} - {{/isSignIn}} - {{#t}}Sign in to Firefox on another device to complete set-up{{/t}} -

- {{/isOther}} + + {{#isMobile}} + {{{ unsupportedPairHtml }}} + {{/isMobile}} {{^isFirefoxDesktop}}
diff --git a/packages/fxa-content-server/app/scripts/templates/pair/index.mustache b/packages/fxa-content-server/app/scripts/templates/pair/index.mustache index bed65082b88..d4d44c392c4 100644 --- a/packages/fxa-content-server/app/scripts/templates/pair/index.mustache +++ b/packages/fxa-content-server/app/scripts/templates/pair/index.mustache @@ -1,89 +1,76 @@
- {{#askMobileStatus}} - {{#needsMobileConfirmed}} - - {{/needsMobileConfirmed}} -

Connect another device

+ {{#showSuccessMessage}} +

{{#t}}Signed in successfully!{{/t}}

+ {{/showSuccessMessage}} - {{^needsMobileConfirmed}} -

{{#t}}Sync your Firefox experience{{/t}}

- {{/needsMobileConfirmed}} - {{#needsMobileConfirmed}} -

{{#t}}Download Firefox for mobile{{/t}}

- {{/needsMobileConfirmed}} + {{#needsMobileConfirmed}} + + {{/needsMobileConfirmed}} - {{/askMobileStatus}} - {{^askMobileStatus}} -

{{#t}}Sync Firefox on your phone or tablet{{/t}}

- {{/askMobileStatus}} +

Connect another device

+ + {{^needsMobileConfirmed}} +

{{#t}}Sync your Firefox experience{{/t}}

+ {{/needsMobileConfirmed}} + {{#needsMobileConfirmed}} +

{{#t}}Download Firefox for mobile{{/t}}

+ {{/needsMobileConfirmed}}
- {{#askMobileStatus}} - {{^needsMobileConfirmed}} -

{{#t}}View your saved passwords, tabs, browsing history and more — across all your devices.{{/t}}

- -
-
- Select an option to continue: -
- - -
-
- - -
+ {{^needsMobileConfirmed}} +

{{#t}}View your saved passwords, tabs, browsing history and more — across all your devices.{{/t}}

-
- + +
+ Select an option to continue: +
+ +
- +
+ + +
-

{{#t}}Not now{{/t}}

- {{/needsMobileConfirmed}} +
+ +
+ - {{#needsMobileConfirmed}} -

{{#t}}To sync Firefox on your phone or tablet, you first need to download Firefox for mobile. Here’s how:{{/t}} -

    -
  1. -

    {{#unsafeTranslate}}Step 1: Download Firefox by scanning this QR code with the camera on your mobile device:{{/unsafeTranslate}}

    - -
  2. -
  3. {{#unsafeTranslate}}Step 2: Select "Continue to sync" to sync your Firefox experience on your mobile device.{{/unsafeTranslate}}
  4. -
+

{{#t}}Not now{{/t}}

+ {{/needsMobileConfirmed}} -
-
- -
-
-

{{#t}}Not now{{/t}}

- {{/needsMobileConfirmed}} - {{/askMobileStatus}} + {{#needsMobileConfirmed}} +

{{#t}}To sync Firefox on your phone or tablet, you first need to download Firefox for mobile. Here’s how:{{/t}} +

    +
  1. +

    {{#unsafeTranslate}}Step 1: Download Firefox by scanning this QR code with the camera on your mobile device:{{/unsafeTranslate}}

    + +
  2. +
  3. {{#unsafeTranslate}}Step 2: Select "Continue to sync" to sync your Firefox experience on your mobile device.{{/unsafeTranslate}}
  4. +
- {{^askMobileStatus}} - -

{{#t}}Take your tabs, bookmarks, and passwords anywhere you use Firefox.{{/t}}

- +
- {{/askMobileStatus}} +

{{#t}}Not now{{/t}}

+ {{/needsMobileConfirmed}}
diff --git a/packages/fxa-content-server/app/scripts/templates/pair/unsupported.mustache b/packages/fxa-content-server/app/scripts/templates/pair/unsupported.mustache index 148c58e5eb2..83374952d67 100644 --- a/packages/fxa-content-server/app/scripts/templates/pair/unsupported.mustache +++ b/packages/fxa-content-server/app/scripts/templates/pair/unsupported.mustache @@ -25,7 +25,7 @@ {{#isMobile}} {{#isSystemCameraUrl}}
-

{{#t}}Pair using an app{{/t}}

+

{{#t}}Pair using an app{{/t}}

{{#t}}Did you use the system camera? You must pair from within a Firefox app.{{/t}}

{{/isSystemCameraUrl}} {{^isSystemCameraUrl}} @@ -37,11 +37,9 @@ {{/isFirefox}} + {{{ unsupportedPairHtml }}} -

{{#t}}Connecting your mobile device with your Mozilla account{{/t}}

-

Open Firefox on your computer, visit firefox.com/pair, and follow the on-screen instructions to connect your mobile device.

-

{{#t}}Learn more{{/t}}

- {{/isSystemCameraUrl}} + {{/isSystemCameraUrl}} {{/isMobile}} {{^isMobile}} {{^isDesktopNonFirefox}} diff --git a/packages/fxa-content-server/app/scripts/templates/partial/unsupported-pair.mustache b/packages/fxa-content-server/app/scripts/templates/partial/unsupported-pair.mustache new file mode 100755 index 00000000000..8827a1af06a --- /dev/null +++ b/packages/fxa-content-server/app/scripts/templates/partial/unsupported-pair.mustache @@ -0,0 +1,5 @@ +

{{#t}}Connecting your mobile device with your Mozilla account{{/t}}

+

Open Firefox on your computer, visit firefox.com/pair, and + follow the on-screen instructions to connect your mobile device.

+

{{#t}}Learn more{{/t}}

\ No newline at end of file diff --git a/packages/fxa-content-server/app/scripts/views/connect_another_device.js b/packages/fxa-content-server/app/scripts/views/connect_another_device.js index e90413c68d4..67da1f38e28 100644 --- a/packages/fxa-content-server/app/scripts/views/connect_another_device.js +++ b/packages/fxa-content-server/app/scripts/views/connect_another_device.js @@ -22,6 +22,7 @@ import MarketingMixin from './mixins/marketing-mixin'; import PairingGraphicsMixin from './mixins/pairing-graphics-mixin'; import SyncAuthMixin from './mixins/sync-auth-mixin'; import VerificationReasonMixin from './mixins/verification-reason-mixin'; +import UnsupportedPairTemplate from '../templates/partial/unsupported-pair.mustache'; const entrypoints = Object.keys(Constants) .filter((k) => k.endsWith('_ENTRYPOINT')) @@ -57,6 +58,17 @@ const ConnectAnotherDeviceView = FormView.extend({ if (this.getSearchParam('redirect_immediately') === 'true') { this.navigate('/settings'); } + + // If users are signed in, directly access this page (no query params) + // on desktop, redirect them + if ( + (this._isSignedIn() && + window.location.search === '' && + !this.getUserAgent().isMobile()) || + this.getSearchParam('entrypoint') === Constants.FIREFOX_AVATAR_ENTRYPOINT + ) { + this.navigate('/pair'); + } }, afterRender() { @@ -182,7 +194,9 @@ const ConnectAnotherDeviceView = FormView.extend({ isSignIn, isSignUp, pairingUrl, + isMobile: this.getUserAgent().isMobile(), showSuccessMessage, + unsupportedPairHtml: this.renderTemplate(UnsupportedPairTemplate), }); }, diff --git a/packages/fxa-content-server/app/scripts/views/mixins/pairing-graphics-mixin.js b/packages/fxa-content-server/app/scripts/views/mixins/pairing-graphics-mixin.js index 12ae4ecb5b9..42770ebe4f5 100644 --- a/packages/fxa-content-server/app/scripts/views/mixins/pairing-graphics-mixin.js +++ b/packages/fxa-content-server/app/scripts/views/mixins/pairing-graphics-mixin.js @@ -10,7 +10,6 @@ */ import UserAgentMixin from '../../lib/user-agent-mixin'; -import Constants from '../../lib/constants'; import UrlMixin from '../../lib/url-mixin'; export default { @@ -23,20 +22,4 @@ export default { } return 'bg-image-cad'; }, - - /** - * Returns true if we believe the current entry points merits that we show the user - * a QR code that can be used download firefox on a mobile device. - */ - showDownloadFirefoxQrCode() { - const entryPoint = this.getSearchParam('entrypoint'); - return ( - entryPoint === Constants.FIREFOX_MENU_ENTRYPOINT || - entryPoint === Constants.FIREFOX_PREFERENCES_ENTRYPOINT || - entryPoint === Constants.FIREFOX_SYNCED_TABS_ENTRYPOINT || - entryPoint === Constants.FIREFOX_TABS_SIDEBAR_ENTRYPOINT || - entryPoint === Constants.FIREFOX_FX_VIEW_ENTRYPOINT || - entryPoint === Constants.FIREFOX_TOOLBAR_ENTRYPOINT - ); - }, }; diff --git a/packages/fxa-content-server/app/scripts/views/pair/index.js b/packages/fxa-content-server/app/scripts/views/pair/index.js index 8e473aaeaa8..70d4ca1d98b 100644 --- a/packages/fxa-content-server/app/scripts/views/pair/index.js +++ b/packages/fxa-content-server/app/scripts/views/pair/index.js @@ -65,23 +65,19 @@ class PairIndexView extends FormView { } setInitialContext(context) { - // Check the entrypoint. If we aren't in a entrypoint=fxa_app_menu context, - // then don't ask if the user needs to download Fx mobile then show QR code. const graphicId = this.getGraphicsId(); - const askMobileStatus = this.showDownloadFirefoxQrCode(); const needsMobileConfirmed = this.model.get('needsMobileConfirmed'); - if (askMobileStatus) { - GleanMetrics.cadFirefox.choiceView(); - } if (needsMobileConfirmed) { GleanMetrics.cadFirefox.view(); + } else { + GleanMetrics.cadFirefox.choiceView(); } context.set({ graphicId, - askMobileStatus, needsMobileConfirmed, + showSuccessMessage: this.showSuccessMessage(), }); } @@ -139,6 +135,13 @@ class PairIndexView extends FormView { GleanMetrics.cadFirefox.choiceNotnowSubmit(); return true; } + + showSuccessMessage() { + return ( + !!this.model.get('showSuccessMessage') || + !!this.getSearchParam('showSuccessMessage') + ); + } } Cocktail.mixin( diff --git a/packages/fxa-content-server/app/scripts/views/pair/unsupported.js b/packages/fxa-content-server/app/scripts/views/pair/unsupported.js index 205b92f029e..5a678c90cc2 100644 --- a/packages/fxa-content-server/app/scripts/views/pair/unsupported.js +++ b/packages/fxa-content-server/app/scripts/views/pair/unsupported.js @@ -8,6 +8,7 @@ import Template from '../../templates/pair/unsupported.mustache'; import GleanMetrics from '../../lib/glean'; import UserAgentMixin from '../../lib/user-agent-mixin'; import UrlMixin from 'lib/url-mixin'; +import UnsupportedPairTemplate from '../../templates/partial/unsupported-pair.mustache'; class PairUnsupportedView extends FormView { template = Template; @@ -24,7 +25,7 @@ class PairUnsupportedView extends FormView { setInitialContext(context) { const uap = this.getUserAgent(); const isFirefox = uap.isFirefox(); - const isMobile = uap.isAndroid() || uap.isIos(); + const isMobile = uap.isMobile(); // Assume the user is on non-Firefox desktop in this case. const isDesktopNonFirefox = !isFirefox && !isMobile; const hashParams = this.getHashParams(['channel_id, channel_key']); @@ -53,6 +54,7 @@ class PairUnsupportedView extends FormView { isSystemCameraUrl, escapedMobileDownloadLink, showCADHeader: !(isMobile && !isSystemCameraUrl), + unsupportedPairHtml: this.renderTemplate(UnsupportedPairTemplate), }); } } diff --git a/packages/fxa-content-server/app/tests/spec/views/connect_another_device.js b/packages/fxa-content-server/app/tests/spec/views/connect_another_device.js index 2bef91fd5a9..f293925260d 100644 --- a/packages/fxa-content-server/app/tests/spec/views/connect_another_device.js +++ b/packages/fxa-content-server/app/tests/spec/views/connect_another_device.js @@ -26,7 +26,7 @@ describe('views/connect_another_device', () => { let windowMock; const FXA_CONNECTED_SELECTOR = '#fxa-connected-heading'; - const FXA_CAD_HEADER = '#fxa-connect-another-device-header'; + const FXA_UNSUPPORTED_HEADER_SELECTOR = '#unsupported-header'; beforeEach(() => { account = new Account(); @@ -65,10 +65,11 @@ describe('views/connect_another_device', () => { describe('render/afterVisible', () => { let viewEventStub; - describe('with a Fx desktop user that is signed in', () => { + describe('with a Fx desktop user that is signed in navigate to pair', () => { beforeEach(() => { viewEventStub = sinon.stub(GleanMetrics.cad, 'view'); sinon.stub(view, '_isSignedIn').callsFake(() => true); + sinon.spy(view, 'navigate'); windowMock.navigator.userAgent = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.12; rv:55.0) Gecko/20100101 Firefox/55.0'; @@ -86,30 +87,8 @@ describe('views/connect_another_device', () => { sinon.assert.calledOnce(viewEventStub); }); - it('shows the pairing link, logs appropriately', () => { - assert.isTrue(view._isSignedIn.called); - assert.lengthOf(view.$('#sync-firefox-devices'), 1); - assert.lengthOf(view.$('#pair-value-prop'), 1); - assert.isTrue( - view - .$('#sync-firefox-devices') - .prop('href') - .endsWith('/pair?entrypoint=fxa_app_menu') - ); - assert.isTrue( - view.$('#cad-not-now').prop('href').endsWith('/settings') - ); - testIsFlowEventLogged('signedin.true'); - testIsFlowEventLogged('signin.ineligible'); - testIsFlowEventLogged('install_from.fx_desktop'); - }); - - it('shows the success message', () => { - assert.lengthOf(view.$(FXA_CONNECTED_SELECTOR), 1); - }); - - it('shows the connect another device header', () => { - assert.lengthOf(view.$(FXA_CAD_HEADER), 1); + it('navigates to pair', () => { + assert.isTrue(view.navigate.calledWith('/pair')); }); }); @@ -173,8 +152,7 @@ describe('views/connect_another_device', () => { 'fxa_app_menu', 'fx-view', ].forEach((entrypoint) => { - describe(`with known entrypoint ${entrypoint} and action=email' - }`, () => { + describe(`with known entrypoint ${entrypoint} and action=email`, () => { beforeEach(() => { viewEventStub = sinon.stub(GleanMetrics.cad, 'view'); sinon.stub(view, '_isSignedIn').callsFake(() => true); @@ -201,59 +179,12 @@ describe('views/connect_another_device', () => { sinon.assert.calledOnce(viewEventStub); }); - it('shows the success message and does not redirect', () => { - assert.lengthOf(view.$(FXA_CONNECTED_SELECTOR), 1); - assert.isTrue(view.navigate.notCalled); - }); - - it('passes the entrypoint param through', () => { - assert.isTrue( - view - .$('#sync-firefox-devices') - .attr('href') - .includes(`entrypoint=${entrypoint}`) - ); + it('navigates to pair', () => { + assert.isTrue(view.navigate.calledWith('/pair')); }); }); }); - describe('with an invalid entrypoint', () => { - beforeEach(() => { - viewEventStub = sinon.stub(GleanMetrics.cad, 'view'); - sinon.stub(view, '_isSignedIn').callsFake(() => true); - sinon.spy(view, 'navigate'); - windowMock.location.search = '?entrypoint=t3st0'; - windowMock.navigator.userAgent = - 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.12; rv:55.0) Gecko/20100101 Firefox/55.0'; - - return view.render().then(() => { - view.afterVisible(); - }); - }); - - afterEach(() => { - viewEventStub.restore(); - }); - - it('logs the view event', () => { - sinon.assert.calledOnce(viewEventStub); - }); - - it('shows the success message and does not redirect', () => { - assert.lengthOf(view.$(FXA_CONNECTED_SELECTOR), 1); - assert.isTrue(view.navigate.notCalled); - }); - - it('sets entrypoint param with to the default', () => { - assert.isTrue( - view - .$('#sync-firefox-devices') - .attr('href') - .includes('entrypoint=fxa_app_menu') - ); - }); - }); - describe('with a fennec user that is signed in', () => { beforeEach(() => { sinon.stub(view, 'getUserAgent').callsFake(() => { @@ -265,6 +196,7 @@ describe('views/connect_another_device', () => { isFirefoxIos: () => false, isIos: () => false, supportsSvgTransformOrigin: () => true, + isMobile: () => true, }; }); @@ -283,8 +215,8 @@ describe('views/connect_another_device', () => { testIsFlowEventLogged('install_from.fx_android'); }); - it('shows the success message', () => { - assert.lengthOf(view.$(FXA_CONNECTED_SELECTOR), 1); + it('shows unsupported messaging', () => { + assert.lengthOf(view.$(FXA_UNSUPPORTED_HEADER_SELECTOR), 1); }); }); @@ -299,6 +231,7 @@ describe('views/connect_another_device', () => { isFirefoxIos: () => false, isIos: () => false, supportsSvgTransformOrigin: () => true, + isMobile: () => false, }; }); @@ -335,6 +268,7 @@ describe('views/connect_another_device', () => { isFirefoxIos: () => false, isIos: () => false, supportsSvgTransformOrigin: () => true, + isMobile: () => true, }; }); @@ -360,103 +294,6 @@ describe('views/connect_another_device', () => { }); }); - describe('with a user that cannot sign in', () => { - beforeEach(() => { - sinon.stub(view, '_isSignedIn').callsFake(() => false); - sinon.stub(view, '_canSignIn').callsFake(() => false); - }); - - it('shows FxiOS help text and marketing area, hides CAD header, to users on FxiOS', () => { - sinon.stub(view, 'getUserAgent').callsFake(() => { - return { - isAndroid: () => false, - isFirefox: () => true, - isFirefoxAndroid: () => false, - isFirefoxDesktop: () => false, - isFirefoxIos: () => true, - isIos: () => true, - supportsSvgTransformOrigin: () => true, - }; - }); - - return view.render().then(() => { - view.afterVisible(); - assert.isTrue(view._isSignedIn.called); - - assert.lengthOf(view.$(FXA_CAD_HEADER), 0); - assert.lengthOf(view.$('#signin-fxios'), 1); - assert.lengthOf(view.$('.marketing-area'), 1); - testIsFlowEventLogged('signin_from.fx_ios'); - }); - }); - - it('shows iOS text, marketing area to users on iOS', () => { - sinon.stub(view, 'getUserAgent').callsFake(() => { - return { - isAndroid: () => false, - isFirefox: () => false, - isFirefoxAndroid: () => false, - isFirefoxDesktop: () => false, - isFirefoxIos: () => false, - isIos: () => true, - supportsSvgTransformOrigin: () => true, - }; - }); - - return view.render().then(() => { - view.afterVisible(); - - assert.lengthOf(view.$('#install-mobile-firefox-ios'), 1); - assert.lengthOf(view.$('.marketing-area'), 1); - testIsFlowEventLogged('install_from.other_ios'); - }); - }); - - it('shows Android text, marketing area to users on Android', () => { - sinon.stub(view, 'getUserAgent').callsFake(() => { - return { - isAndroid: () => true, - isFirefox: () => false, - isFirefoxAndroid: () => false, - isFirefoxDesktop: () => false, - isFirefoxIos: () => false, - isIos: () => false, - supportsSvgTransformOrigin: () => true, - }; - }); - - return view.render().then(() => { - view.afterVisible(); - - assert.lengthOf(view.$('#install-mobile-firefox-android'), 1); - assert.lengthOf(view.$('.marketing-area'), 1); - testIsFlowEventLogged('install_from.other_android'); - }); - }); - - it('shows Other text, marketing area to everyone else', () => { - sinon.stub(view, 'getUserAgent').callsFake(() => { - return { - isAndroid: () => false, - isFirefox: () => false, - isFirefoxAndroid: () => false, - isFirefoxDesktop: () => false, - isFirefoxIos: () => false, - isIos: () => false, - supportsSvgTransformOrigin: () => true, - }; - }); - - return view.render().then(() => { - view.afterVisible(); - - assert.lengthOf(view.$('#install-mobile-firefox-other'), 1); - assert.lengthOf(view.$('.marketing-area'), 1); - testIsFlowEventLogged('install_from.other'); - }); - }); - }); - describe('with showSuccessMessage set to false', () => { beforeEach(() => { model.set('showSuccessMessage', false); @@ -475,24 +312,6 @@ describe('views/connect_another_device', () => { }); }); - describe('with showSuccessMessage in the search params', () => { - beforeEach(() => { - sinon.stub(view, '_isSignedIn').callsFake(() => true); - - windowMock.navigator.userAgent = - 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.12; rv:55.0) Gecko/20100101 Firefox/55.0'; - windowMock.location.search = 'showSuccessMessage=true'; - - return view.render().then(() => { - view.afterVisible(); - }); - }); - - it('shows the success message', () => { - assert.lengthOf(view.$(FXA_CONNECTED_SELECTOR), 1); - }); - }); - describe('with a Fx desktop sync declined user', () => { beforeEach(() => { sinon.stub(view, '_isSignedIn').callsFake(() => true); @@ -500,24 +319,15 @@ describe('views/connect_another_device', () => { windowMock.navigator.userAgent = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.12; rv:55.0) Gecko/20100101 Firefox/55.0'; - + sinon.spy(view, 'navigate'); return view.render().then(() => { view.afterVisible(); }); }); - it('shows the marketing area, logs appropriately', () => { - assert.isTrue(view._isSignedIn.called); - assert.isTrue( - view.$('#cad-not-now').prop('href').endsWith('/settings') - ); - testIsFlowEventLogged('signedin.true'); - testIsFlowEventLogged('signin.ineligible'); - testIsFlowEventLogged('install_from.fx_desktop'); - }); - - it('shows the success message', () => { - assert.lengthOf(view.$(FXA_CONNECTED_SELECTOR), 1); + it('navigates to pair', () => { + // Even though Sync isn't enabled, a user can still pair a device + assert.isTrue(view.navigate.calledWith('/pair')); }); }); }); @@ -625,6 +435,7 @@ describe('views/connect_another_device', () => { isFirefoxIos: () => false, isIos: () => false, supportsSvgTransformOrigin: () => true, + isMobile: () => false, }; }); @@ -647,38 +458,4 @@ describe('views/connect_another_device', () => { }); }); }); - - describe('svg-graphic', () => { - const userAgentObj = { - isAndroid: () => false, - isFirefox: () => true, - isFirefoxAndroid: () => false, - isFirefoxDesktop: () => true, - isFirefoxIos: () => false, - isIos: () => false, - supportsSvgTransformOrigin: () => true, - }; - - beforeEach(() => { - account.set('email', 'testuser@testuser.com'); - sinon.stub(user, 'isSignedInAccount').callsFake(() => false); - sinon.stub(view, '_canSignIn').callsFake(() => true); - return view.render(); - }); - - it('shows animated hearts where supportsSvgTransformOrigin is supported', () => { - sinon.stub(view, 'getUserAgent').callsFake(() => userAgentObj); - assert.equal(view.$el.find('.bg-image-triple-device-hearts').length, 1); - assert.equal(view.$el.find('.bg-image-cad').length, 0); - }); - - it('shows non-animated hearts where supportsSvgTransformOrigin is not supported', () => { - userAgentObj.supportsSvgTransformOrigin = () => false; - sinon.stub(view, 'getUserAgent').callsFake(() => userAgentObj); - return view.render().then(() => { - assert.equal(view.$el.find('.bg-image-triple-device-hearts').length, 0); - assert.equal(view.$el.find('.bg-image-cad').length, 1); - }); - }); - }); }); diff --git a/packages/fxa-content-server/app/tests/spec/views/mixins/pairing-graphics-mixin.js b/packages/fxa-content-server/app/tests/spec/views/mixins/pairing-graphics-mixin.js index 69acc74e649..0504ad6e6bd 100644 --- a/packages/fxa-content-server/app/tests/spec/views/mixins/pairing-graphics-mixin.js +++ b/packages/fxa-content-server/app/tests/spec/views/mixins/pairing-graphics-mixin.js @@ -38,41 +38,4 @@ describe('views/mixins/pairing-graphics-mixin', function () { assert.equal(view.getGraphicsId(), 'bg-image-triple-device-hearts'); }); }); - - describe('showDownloadFirefoxQrCode', () => { - it('returns true if entry point is app menu', () => { - sinon.stub(view, 'getSearchParam').callsFake(() => 'fxa_app_menu'); - assert.equal(view.showDownloadFirefoxQrCode(), true); - }); - - it('returns true if entry point is preferences', () => { - sinon.stub(view, 'getSearchParam').callsFake(() => 'preferences'); - assert.equal(view.showDownloadFirefoxQrCode(), true); - }); - - it('returns true if entry point is synced-tabs', () => { - sinon.stub(view, 'getSearchParam').callsFake(() => 'synced-tabs'); - assert.equal(view.showDownloadFirefoxQrCode(), true); - }); - - it('returns true if entry point is side-bar', () => { - sinon.stub(view, 'getSearchParam').callsFake(() => 'tabs-sidebar'); - assert.equal(view.showDownloadFirefoxQrCode(), true); - }); - - it('returns true if entry point is fx-view', () => { - sinon.stub(view, 'getSearchParam').callsFake(() => 'fx-view'); - assert.equal(view.showDownloadFirefoxQrCode(), true); - }); - - it('returns true if entry point is fxa_discoverability_native', () => { - sinon.stub(view, 'getSearchParam').callsFake(() => 'fx-view'); - assert.equal(view.showDownloadFirefoxQrCode(), true); - }); - - it('returns false if entry point is not app menu', () => { - sinon.stub(view, 'getSearchParam').callsFake(() => undefined); - assert.equal(view.showDownloadFirefoxQrCode(), false); - }); - }); }); diff --git a/packages/fxa-content-server/app/tests/spec/views/pair/index.js b/packages/fxa-content-server/app/tests/spec/views/pair/index.js index 9a6c90b06bd..4ec96a2b5aa 100644 --- a/packages/fxa-content-server/app/tests/spec/views/pair/index.js +++ b/packages/fxa-content-server/app/tests/spec/views/pair/index.js @@ -132,8 +132,6 @@ describe('views/pair/index', () => { view.$el.find('#pair-header').text(), 'Download Firefox on your phone or tablet' ); - assert.ok(view.$el.find('#start-pairing').length); - assert.ok(view.$el.find('.bg-image-triple-device-hearts').length); }); }); @@ -172,7 +170,6 @@ describe('views/pair/index', () => { let viewChoiceEventStub; beforeEach(() => { viewChoiceEventStub = sinon.stub(GleanMetrics.cadFirefox, 'choiceView'); - sinon.stub(view, 'showDownloadFirefoxQrCode').callsFake(() => true); return view.render(); }); @@ -383,7 +380,6 @@ describe('views/pair/index', () => { describe('pairNotNowHandler', () => { let notNowEventStub; beforeEach(() => { - sinon.stub(view, 'showDownloadFirefoxQrCode').callsFake(() => true); notNowEventStub = sinon.stub(GleanMetrics.cadFirefox, 'notnowSubmit'); }); afterEach(() => { @@ -397,23 +393,6 @@ describe('views/pair/index', () => { }); }); }); - - it('does not ask for mobile status', () => { - sinon.stub(view, 'showDownloadFirefoxQrCode').callsFake(() => false); - return view.render().then(() => { - const heading = view.$('#pair-header'); - assert.strictEqual( - heading.text(), - 'Sync Firefox on your phone or tablet' - ); - - const pairButton = view.$('#start-pairing'); - assert.equal(pairButton.length, 1); - - const qrCode = view.$el.find('.bg-image-cad-qr-code'); - assert.equal(qrCode.length, 0); - }); - }); }); describe('submit', () => { diff --git a/packages/fxa-content-server/app/tests/spec/views/pair/unsupported.js b/packages/fxa-content-server/app/tests/spec/views/pair/unsupported.js index 0468d7816d1..e716ffb3a14 100644 --- a/packages/fxa-content-server/app/tests/spec/views/pair/unsupported.js +++ b/packages/fxa-content-server/app/tests/spec/views/pair/unsupported.js @@ -55,6 +55,7 @@ describe('views/pair/unsupported', () => { isAndroid: () => false, isFirefox: () => true, isIos: () => true, + isMobile: () => true, }; }); sinon.stub(view, 'getHashParams').callsFake(() => { @@ -95,6 +96,7 @@ describe('views/pair/unsupported', () => { isAndroid: () => false, isFirefox: () => true, isIos: () => true, + isMobile: () => true, }; }); }); @@ -139,6 +141,7 @@ describe('views/pair/unsupported', () => { isAndroid: () => true, isFirefox: () => false, isIos: () => false, + isMobile: () => true, }; }); }); @@ -180,6 +183,7 @@ describe('views/pair/unsupported', () => { isAndroid: () => false, isFirefox: () => true, isIos: () => false, + isMobile: () => false, }; }); }); @@ -213,6 +217,7 @@ describe('views/pair/unsupported', () => { isAndroid: () => false, isFirefox: () => false, isIos: () => false, + isMobile: () => false, }; }); }); diff --git a/packages/fxa-settings/src/pages/InlineRecoveryKeySetup/container.test.tsx b/packages/fxa-settings/src/pages/InlineRecoveryKeySetup/container.test.tsx index 4aa60bc67bc..81a6acd9202 100644 --- a/packages/fxa-settings/src/pages/InlineRecoveryKeySetup/container.test.tsx +++ b/packages/fxa-settings/src/pages/InlineRecoveryKeySetup/container.test.tsx @@ -111,7 +111,7 @@ describe('InlineRecoveryKeySetupContainer', () => { render(); expect(hardNavigateSpy).toHaveBeenCalledWith( - '/connect_another_device?showSuccessMessage=true' + '/pair?showSuccessMessage=true' ); expect(InlineRecoveryKeySetupModule.default).not.toBeCalled(); }); diff --git a/packages/fxa-settings/src/pages/Signin/SigninPushCode/container.test.tsx b/packages/fxa-settings/src/pages/Signin/SigninPushCode/container.test.tsx index 8bd80738aec..9a651bb6c7e 100644 --- a/packages/fxa-settings/src/pages/Signin/SigninPushCode/container.test.tsx +++ b/packages/fxa-settings/src/pages/Signin/SigninPushCode/container.test.tsx @@ -211,7 +211,7 @@ describe('SigninPushCode container', () => { await render(); }); expect(ReactUtils.hardNavigate).toBeCalledWith( - '/connect_another_device?showSuccessMessage=true' + '/pair?showSuccessMessage=true' ); }); }); diff --git a/packages/fxa-settings/src/pages/Signin/SigninTotpCode/index.test.tsx b/packages/fxa-settings/src/pages/Signin/SigninTotpCode/index.test.tsx index 30d68dcbda7..3e35dbcdb82 100644 --- a/packages/fxa-settings/src/pages/Signin/SigninTotpCode/index.test.tsx +++ b/packages/fxa-settings/src/pages/Signin/SigninTotpCode/index.test.tsx @@ -175,7 +175,7 @@ describe('Sign in with TOTP code page', () => { ); expect(fxaLoginSpy).toHaveBeenCalled(); expect(hardNavigateSpy).toHaveBeenCalledWith( - '/connect_another_device?showSuccessMessage=true' + '/pair?showSuccessMessage=true' ); }); it('is not sent otherwise', async () => { diff --git a/packages/fxa-settings/src/pages/Signin/index.test.tsx b/packages/fxa-settings/src/pages/Signin/index.test.tsx index efe792aece9..b258ba87556 100644 --- a/packages/fxa-settings/src/pages/Signin/index.test.tsx +++ b/packages/fxa-settings/src/pages/Signin/index.test.tsx @@ -422,7 +422,7 @@ describe('Signin', () => { expect(fxaLoginSpy).toHaveBeenCalled(); }); expect(hardNavigateSpy).toHaveBeenCalledWith( - '/connect_another_device?showSuccessMessage=true' + '/pair?showSuccessMessage=true' ); }); it('is not sent if user has 2FA enabled', async () => { @@ -561,7 +561,7 @@ describe('Signin', () => { expect(fxaLoginSpy).toHaveBeenCalled(); expect(fxaOAuthLoginSpy).toHaveBeenCalled(); expect(hardNavigateSpy).toHaveBeenCalledWith( - '/connect_another_device?showSuccessMessage=true' + '/pair?showSuccessMessage=true' ); }); }); diff --git a/packages/fxa-settings/src/pages/Signin/utils.ts b/packages/fxa-settings/src/pages/Signin/utils.ts index a02b783cc47..79864b84b4c 100644 --- a/packages/fxa-settings/src/pages/Signin/utils.ts +++ b/packages/fxa-settings/src/pages/Signin/utils.ts @@ -42,7 +42,7 @@ export function getSyncNavigate( searchParams.set('showSuccessMessage', 'true'); return { - to: `/connect_another_device?${searchParams}`, + to: `/pair?${searchParams}`, shouldHardNavigate: true, }; }