зеркало из https://github.com/mozilla/fxa.git
Merge pull request #15861 from mozilla/create-smoke-test-suite
config(functional): remove content-server-remote steps for old tests
This commit is contained in:
Коммит
df2685bfac
|
@ -265,28 +265,6 @@ commands:
|
|||
- fxa-yarn-001-{{ checksum "yarn.lock" }}
|
||||
- fxa-yarn-001-
|
||||
|
||||
test-content-server-remote-part:
|
||||
parameters:
|
||||
index:
|
||||
type: integer
|
||||
total:
|
||||
type: integer
|
||||
steps:
|
||||
- git-checkout
|
||||
- provision
|
||||
- run:
|
||||
name: Running test section << parameters.index >> of << parameters.total >>
|
||||
environment:
|
||||
CIRCLE_NODE_INDEX: << parameters.index >>
|
||||
CIRCLE_NODE_TOTAL: << parameters.total >>
|
||||
ACCOUNTS_DOMAIN: << pipeline.parameters.accounts-domain >>
|
||||
PAYMENTS_DOMAIN: << pipeline.parameters.payments-domain >>
|
||||
ACCOUNTS_API_DOMAIN: << pipeline.parameters.accounts-api-domain >>
|
||||
RELIER_DOMAIN: << pipeline.parameters.relier-domain >>
|
||||
UNTRUSTED_RELIER_DOMAIN: << pipeline.parameters.untrusted-relier-domain >>
|
||||
command: ./packages/fxa-content-server/scripts/test-ci-remote.sh
|
||||
- store-artifacts
|
||||
|
||||
wait-for-infrastructure:
|
||||
steps:
|
||||
- run:
|
||||
|
@ -329,14 +307,20 @@ commands:
|
|||
command: |
|
||||
if [[ "<< parameters.project >>" == "production" ]]; then
|
||||
export FEATURE_FLAGS_SHOW_RECOVERY_KEY_V2=true
|
||||
GREP="--grep=\"severity-1\""
|
||||
elif [[ "<< parameters.project >>" == "stage" ]]; then
|
||||
export FEATURE_FLAGS_SHOW_RECOVERY_KEY_V2=true
|
||||
GREP="--grep=\"severity-(1|2)\""
|
||||
else
|
||||
export FEATURE_FLAGS_SHOW_RECOVERY_KEY_V2=true
|
||||
GREP=""
|
||||
fi
|
||||
echo "targeting project << parameters.project >> $GREP"
|
||||
npx nx build fxa-auth-client
|
||||
cd packages/functional-tests/tests
|
||||
TEST_FILES=$(circleci tests glob "./**/*.spec.ts")
|
||||
cd ..
|
||||
echo $TEST_FILES | circleci tests run --command="xargs yarn playwright test --project=<< parameters.project >>" --verbose --split-by=timings
|
||||
echo $TEST_FILES | circleci tests run --command="xargs yarn playwright test --project=<< parameters.project >> $GREP" --verbose --split-by=timings
|
||||
environment:
|
||||
NODE_OPTIONS: --dns-result-order=ipv4first
|
||||
JEST_JUNIT_OUTPUT_DIR: ./artifacts/tests
|
||||
|
@ -620,37 +604,6 @@ jobs:
|
|||
no_output_timeout: 20m
|
||||
- store-artifacts
|
||||
|
||||
# This job is manually triggered for now. see .circleci/README.md
|
||||
test-content-server-remote:
|
||||
executor: smoke-test-executor
|
||||
steps:
|
||||
- git-checkout
|
||||
- provision
|
||||
- run:
|
||||
name: Running test section against a remote target
|
||||
command: ./packages/fxa-content-server/scripts/test-ci-remote.sh
|
||||
- store-artifacts
|
||||
|
||||
# These jobs are manually triggered for now. see .circleci/README.md
|
||||
test-content-server-remote-part-0:
|
||||
executor: smoke-test-executor
|
||||
steps:
|
||||
- test-content-server-remote-part:
|
||||
index: 0
|
||||
total: 3
|
||||
test-content-server-remote-part-1:
|
||||
executor: smoke-test-executor
|
||||
steps:
|
||||
- test-content-server-remote-part:
|
||||
index: 1
|
||||
total: 3
|
||||
test-content-server-remote-part-2:
|
||||
executor: smoke-test-executor
|
||||
steps:
|
||||
- test-content-server-remote-part:
|
||||
index: 2
|
||||
total: 3
|
||||
|
||||
# Deprecated - use workflows in conjunction with smoke-tests job instead!
|
||||
# This job is manually triggered for now. see .circleci/README.md
|
||||
production-smoke-tests:
|
||||
|
|
|
@ -4,73 +4,75 @@
|
|||
|
||||
import { test, expect } from '../../lib/fixtures/standard';
|
||||
|
||||
test.describe('force auth', () => {
|
||||
test.beforeEach(async ({ pages: { configPage } }) => {
|
||||
const config = await configPage.getConfig();
|
||||
// TODO: Remove forceAuth tests. React pages don't have this flow.
|
||||
test.skip(config.showReactApp.resetPasswordRoutes === true);
|
||||
});
|
||||
test('with a registered email, registered uid', async ({
|
||||
credentials,
|
||||
pages: { login, forceAuth },
|
||||
}) => {
|
||||
await forceAuth.open(credentials);
|
||||
await login.setPassword(credentials.password);
|
||||
await login.submit();
|
||||
expect(await login.isUserLoggedIn()).toBe(true);
|
||||
});
|
||||
test.describe('severity-1 #smoke', () => {
|
||||
test.describe('force auth', () => {
|
||||
test.beforeEach(async ({ pages: { configPage } }) => {
|
||||
const config = await configPage.getConfig();
|
||||
// TODO: Remove forceAuth tests. React pages don't have this flow.
|
||||
test.skip(config.showReactApp.resetPasswordRoutes === true);
|
||||
});
|
||||
test('with a registered email, registered uid', async ({
|
||||
credentials,
|
||||
pages: { login, forceAuth },
|
||||
}) => {
|
||||
await forceAuth.open(credentials);
|
||||
await login.setPassword(credentials.password);
|
||||
await login.submit();
|
||||
expect(await login.isUserLoggedIn()).toBe(true);
|
||||
});
|
||||
|
||||
test('forgot password flow via force_auth', async ({
|
||||
credentials,
|
||||
pages: { login, resetPassword, forceAuth },
|
||||
}) => {
|
||||
await forceAuth.open(credentials);
|
||||
await login.clickForgotPassword();
|
||||
test('forgot password flow via force_auth', async ({
|
||||
credentials,
|
||||
pages: { login, resetPassword, forceAuth },
|
||||
}) => {
|
||||
await forceAuth.open(credentials);
|
||||
await login.clickForgotPassword();
|
||||
|
||||
// Verify reset password header
|
||||
await resetPassword.resetPasswordHeader();
|
||||
// Verify reset password header
|
||||
await resetPassword.resetPasswordHeader();
|
||||
|
||||
//Verify email is prefilled
|
||||
expect(await login.getPrefilledEmail()).toContain(credentials.email);
|
||||
//Verify email is prefilled
|
||||
expect(await login.getPrefilledEmail()).toContain(credentials.email);
|
||||
|
||||
//Click 'Remember password? Sign in', redirected to force auth page
|
||||
await resetPassword.clickRememberPassword();
|
||||
expect(await login.getPrefilledEmail()).toContain(credentials.email);
|
||||
//Click 'Remember password? Sign in', redirected to force auth page
|
||||
await resetPassword.clickRememberPassword();
|
||||
expect(await login.getPrefilledEmail()).toContain(credentials.email);
|
||||
|
||||
//Click forgot password again
|
||||
await login.clickForgotPassword();
|
||||
await resetPassword.clickBeginReset();
|
||||
//Click forgot password again
|
||||
await login.clickForgotPassword();
|
||||
await resetPassword.clickBeginReset();
|
||||
|
||||
//Verify confirm reset password header
|
||||
await resetPassword.confirmResetPasswordHeader();
|
||||
//Verify confirm reset password header
|
||||
await resetPassword.confirmResetPasswordHeader();
|
||||
|
||||
//Click 'Remember password? Sign in', redirected to force auth page
|
||||
await resetPassword.clickRememberPassword();
|
||||
expect(await login.getPrefilledEmail()).toContain(credentials.email);
|
||||
});
|
||||
//Click 'Remember password? Sign in', redirected to force auth page
|
||||
await resetPassword.clickRememberPassword();
|
||||
expect(await login.getPrefilledEmail()).toContain(credentials.email);
|
||||
});
|
||||
|
||||
test('form prefill information is cleared after sign in->sign out', async ({
|
||||
credentials,
|
||||
pages: { login, forceAuth, settings },
|
||||
}) => {
|
||||
await forceAuth.open(credentials);
|
||||
await login.setPassword(credentials.password);
|
||||
await login.submit();
|
||||
expect(await login.isUserLoggedIn()).toBe(true);
|
||||
test('form prefill information is cleared after sign in->sign out', async ({
|
||||
credentials,
|
||||
pages: { login, forceAuth, settings },
|
||||
}) => {
|
||||
await forceAuth.open(credentials);
|
||||
await login.setPassword(credentials.password);
|
||||
await login.submit();
|
||||
expect(await login.isUserLoggedIn()).toBe(true);
|
||||
|
||||
//Sign out
|
||||
await settings.signOut();
|
||||
//Sign out
|
||||
await settings.signOut();
|
||||
|
||||
//Verify user need to enter email
|
||||
await login.waitForEmailHeader();
|
||||
await login.setEmail(credentials.email);
|
||||
await login.submit();
|
||||
//Verify user need to enter email
|
||||
await login.waitForEmailHeader();
|
||||
await login.setEmail(credentials.email);
|
||||
await login.submit();
|
||||
|
||||
//Verify password is empty and user need to enter password
|
||||
await login.waitForPasswordHeader();
|
||||
expect(await login.getPasswordInput()).toContain('');
|
||||
await login.setPassword(credentials.password);
|
||||
await login.submit();
|
||||
expect(await login.isUserLoggedIn()).toBe(true);
|
||||
//Verify password is empty and user need to enter password
|
||||
await login.waitForPasswordHeader();
|
||||
expect(await login.getPasswordInput()).toContain('');
|
||||
await login.setPassword(credentials.password);
|
||||
await login.submit();
|
||||
expect(await login.isUserLoggedIn()).toBe(true);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -1,3 +1,7 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
import { test, expect } from '../../lib/fixtures/standard';
|
||||
|
||||
test.describe('404', () => {
|
||||
|
|
|
@ -1,70 +1,77 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
import { test, expect } from '../../lib/fixtures/standard';
|
||||
|
||||
test.describe('OAuth force auth', () => {
|
||||
test.beforeEach(async ({ pages: { configPage } }) => {
|
||||
const config = await configPage.getConfig();
|
||||
// TODO: Remove forceAuth tests. React pages don't have this flow.
|
||||
test.skip(config.showReactApp.resetPasswordRoutes === true);
|
||||
});
|
||||
test('with a registered email', async ({
|
||||
credentials,
|
||||
pages: { login, relier },
|
||||
}) => {
|
||||
await relier.goto(`email=${credentials.email}`);
|
||||
await relier.clickForceAuth();
|
||||
test.describe('severity-1 #smoke', () => {
|
||||
test.describe('OAuth force auth', () => {
|
||||
test.beforeEach(async ({ pages: { configPage } }) => {
|
||||
const config = await configPage.getConfig();
|
||||
// TODO: Remove forceAuth tests. React pages don't have this flow.
|
||||
test.skip(config.showReactApp.resetPasswordRoutes === true);
|
||||
});
|
||||
test('with a registered email', async ({
|
||||
credentials,
|
||||
pages: { login, relier },
|
||||
}) => {
|
||||
await relier.goto(`email=${credentials.email}`);
|
||||
await relier.clickForceAuth();
|
||||
|
||||
// Email is prefilled
|
||||
await expect(await login.page.innerText('#prefillEmail')).toContain(
|
||||
credentials.email
|
||||
);
|
||||
await login.setPassword(credentials.password);
|
||||
await login.submit();
|
||||
expect(await relier.isLoggedIn()).toBe(true);
|
||||
});
|
||||
// Email is prefilled
|
||||
await expect(await login.page.innerText('#prefillEmail')).toContain(
|
||||
credentials.email
|
||||
);
|
||||
await login.setPassword(credentials.password);
|
||||
await login.submit();
|
||||
expect(await relier.isLoggedIn()).toBe(true);
|
||||
});
|
||||
|
||||
test('with a unregistered email', async ({
|
||||
credentials,
|
||||
pages: { login, relier },
|
||||
}, { project }) => {
|
||||
test.slow(project.name !== 'local', 'email delivery can be slow');
|
||||
const newEmail = `${Date.now()}@restmail.net`;
|
||||
await relier.goto(`email=${newEmail}`);
|
||||
await relier.clickForceAuth();
|
||||
test('with a unregistered email', async ({
|
||||
credentials,
|
||||
pages: { login, relier },
|
||||
}, { project }) => {
|
||||
test.slow(project.name !== 'local', 'email delivery can be slow');
|
||||
const newEmail = `${Date.now()}@restmail.net`;
|
||||
await relier.goto(`email=${newEmail}`);
|
||||
await relier.clickForceAuth();
|
||||
|
||||
// Signup form is shown and email is prefilled
|
||||
await expect(await login.getPrefilledEmail()).toContain(newEmail);
|
||||
await login.setAge('21');
|
||||
await login.setNewPassword(credentials.password);
|
||||
await login.fillOutSignUpCode(newEmail);
|
||||
// Signup form is shown and email is prefilled
|
||||
await expect(await login.getPrefilledEmail()).toContain(newEmail);
|
||||
await login.setAge('21');
|
||||
await login.setNewPassword(credentials.password);
|
||||
await login.fillOutSignUpCode(newEmail);
|
||||
|
||||
expect(await relier.isLoggedIn()).toBe(true);
|
||||
});
|
||||
expect(await relier.isLoggedIn()).toBe(true);
|
||||
});
|
||||
|
||||
test('with blocked email', async ({ credentials, pages: { login, relier } }, {
|
||||
project,
|
||||
}) => {
|
||||
test.slow(project.name !== 'local', 'email delivery can be slow');
|
||||
test('with blocked email', async ({
|
||||
credentials,
|
||||
pages: { login, relier },
|
||||
}, { project }) => {
|
||||
test.slow(project.name !== 'local', 'email delivery can be slow');
|
||||
|
||||
const blockedEmail = `blocked${Date.now()}@restmail.net`;
|
||||
await relier.goto(`email=${blockedEmail}`);
|
||||
await relier.clickForceAuth();
|
||||
const blockedEmail = `blocked${Date.now()}@restmail.net`;
|
||||
await relier.goto(`email=${blockedEmail}`);
|
||||
await relier.clickForceAuth();
|
||||
|
||||
await expect(await login.getPrefilledEmail()).toContain(blockedEmail);
|
||||
await login.setAge('21');
|
||||
await login.setNewPassword(credentials.password);
|
||||
await login.fillOutSignUpCode(blockedEmail);
|
||||
await expect(await login.getPrefilledEmail()).toContain(blockedEmail);
|
||||
await login.setAge('21');
|
||||
await login.setNewPassword(credentials.password);
|
||||
await login.fillOutSignUpCode(blockedEmail);
|
||||
|
||||
expect(await relier.isLoggedIn()).toBe(true);
|
||||
expect(await relier.isLoggedIn()).toBe(true);
|
||||
|
||||
await relier.signOut();
|
||||
await relier.signOut();
|
||||
|
||||
// Attempt to log in again which will show the blocked page
|
||||
await relier.goto(`email=${blockedEmail}`);
|
||||
await relier.clickForceAuth();
|
||||
await login.setPassword(credentials.password);
|
||||
await login.submit();
|
||||
// Attempt to log in again which will show the blocked page
|
||||
await relier.goto(`email=${blockedEmail}`);
|
||||
await relier.clickForceAuth();
|
||||
await login.setPassword(credentials.password);
|
||||
await login.submit();
|
||||
|
||||
await login.unblock(blockedEmail);
|
||||
expect(await relier.isLoggedIn()).toBe(true);
|
||||
await login.unblock(blockedEmail);
|
||||
expect(await relier.isLoggedIn()).toBe(true);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -1,97 +1,103 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
import { test, expect } from '../../lib/fixtures/standard';
|
||||
|
||||
const PASSWORD = 'passwordzxcv';
|
||||
|
||||
test.describe('OAuth `login_hint` and `email` param', () => {
|
||||
test('email specified by relier, invalid', async ({
|
||||
pages: { login, relier },
|
||||
}) => {
|
||||
const invalidEmail = 'invalid@';
|
||||
await relier.goto(`email=${invalidEmail}`);
|
||||
await relier.clickEmailFirst();
|
||||
const error = await login.getTooltipError();
|
||||
expect(error).toContain('Valid email required');
|
||||
});
|
||||
test.describe('severity-2 #smoke', () => {
|
||||
test.describe('OAuth `login_hint` and `email` param', () => {
|
||||
test('email specified by relier, invalid', async ({
|
||||
pages: { login, relier },
|
||||
}) => {
|
||||
const invalidEmail = 'invalid@';
|
||||
await relier.goto(`email=${invalidEmail}`);
|
||||
await relier.clickEmailFirst();
|
||||
const error = await login.getTooltipError();
|
||||
expect(error).toContain('Valid email required');
|
||||
});
|
||||
|
||||
test('login_hint specified by relier, not registered', async ({
|
||||
pages: { login, relier },
|
||||
}) => {
|
||||
const email = login.createEmail();
|
||||
await relier.goto(`login_hint=${email}`);
|
||||
await relier.clickEmailFirst();
|
||||
test('login_hint specified by relier, not registered', async ({
|
||||
pages: { login, relier },
|
||||
}) => {
|
||||
const email = login.createEmail();
|
||||
await relier.goto(`login_hint=${email}`);
|
||||
await relier.clickEmailFirst();
|
||||
|
||||
// Email is prefilled
|
||||
await expect(await login.getPrefilledEmail()).toEqual(email);
|
||||
expect(await login.signUpPasswordHeader()).toEqual(true);
|
||||
// Email is prefilled
|
||||
await expect(await login.getPrefilledEmail()).toEqual(email);
|
||||
expect(await login.signUpPasswordHeader()).toEqual(true);
|
||||
|
||||
await login.useDifferentAccountLink();
|
||||
await login.useDifferentAccountLink();
|
||||
|
||||
// Email first page has email input prefilled
|
||||
await expect(await login.getEmailInput()).toEqual(email);
|
||||
});
|
||||
// Email first page has email input prefilled
|
||||
await expect(await login.getEmailInput()).toEqual(email);
|
||||
});
|
||||
|
||||
test('email specified by relier, registered', async ({
|
||||
credentials,
|
||||
pages: { login, relier },
|
||||
}) => {
|
||||
await relier.goto(`email=${credentials.email}`);
|
||||
await relier.clickEmailFirst();
|
||||
test('email specified by relier, registered', async ({
|
||||
credentials,
|
||||
pages: { login, relier },
|
||||
}) => {
|
||||
await relier.goto(`email=${credentials.email}`);
|
||||
await relier.clickEmailFirst();
|
||||
|
||||
// Email is prefilled
|
||||
await expect(await login.getPrefilledEmail()).toEqual(credentials.email);
|
||||
expect(await login.signInPasswordHeader()).toEqual(true);
|
||||
// Email is prefilled
|
||||
await expect(await login.getPrefilledEmail()).toEqual(credentials.email);
|
||||
expect(await login.signInPasswordHeader()).toEqual(true);
|
||||
|
||||
await login.useDifferentAccountLink();
|
||||
await login.useDifferentAccountLink();
|
||||
|
||||
// Email first page has email input prefilled
|
||||
await expect(await login.getEmailInput()).toEqual(credentials.email);
|
||||
});
|
||||
// Email first page has email input prefilled
|
||||
await expect(await login.getEmailInput()).toEqual(credentials.email);
|
||||
});
|
||||
|
||||
test('login_hint specified by relier, registered', async ({
|
||||
credentials,
|
||||
pages: { login, relier },
|
||||
}) => {
|
||||
await relier.goto(`login_hint=${credentials.email}`);
|
||||
await relier.clickEmailFirst();
|
||||
test('login_hint specified by relier, registered', async ({
|
||||
credentials,
|
||||
pages: { login, relier },
|
||||
}) => {
|
||||
await relier.goto(`login_hint=${credentials.email}`);
|
||||
await relier.clickEmailFirst();
|
||||
|
||||
// Email is prefilled
|
||||
await expect(await login.getPrefilledEmail()).toEqual(credentials.email);
|
||||
expect(await login.signInPasswordHeader()).toEqual(true);
|
||||
// Email is prefilled
|
||||
await expect(await login.getPrefilledEmail()).toEqual(credentials.email);
|
||||
expect(await login.signInPasswordHeader()).toEqual(true);
|
||||
|
||||
await login.useDifferentAccountLink();
|
||||
await login.useDifferentAccountLink();
|
||||
|
||||
// Email first page has email input prefilled
|
||||
await expect(await login.getEmailInput()).toEqual(credentials.email);
|
||||
});
|
||||
// Email first page has email input prefilled
|
||||
await expect(await login.getEmailInput()).toEqual(credentials.email);
|
||||
});
|
||||
|
||||
test('cached credentials, login_hint specified by relier', async ({
|
||||
target,
|
||||
pages: { login, relier },
|
||||
}) => {
|
||||
const email = login.createEmail();
|
||||
await target.createAccount(email, PASSWORD);
|
||||
test('cached credentials, login_hint specified by relier', async ({
|
||||
target,
|
||||
pages: { login, relier },
|
||||
}) => {
|
||||
const email = login.createEmail();
|
||||
await target.createAccount(email, PASSWORD);
|
||||
|
||||
const loginHintEmail = login.createEmail();
|
||||
await target.createAccount(loginHintEmail, PASSWORD);
|
||||
const loginHintEmail = login.createEmail();
|
||||
await target.createAccount(loginHintEmail, PASSWORD);
|
||||
|
||||
// Create a cached login
|
||||
await relier.goto();
|
||||
await relier.clickEmailFirst();
|
||||
await login.login(email, PASSWORD);
|
||||
expect(await relier.isLoggedIn()).toBe(true);
|
||||
await relier.signOut();
|
||||
// Create a cached login
|
||||
await relier.goto();
|
||||
await relier.clickEmailFirst();
|
||||
await login.login(email, PASSWORD);
|
||||
expect(await relier.isLoggedIn()).toBe(true);
|
||||
await relier.signOut();
|
||||
|
||||
// login_hint takes precedence over the signed-in user
|
||||
await relier.goto(`login_hint=${loginHintEmail}`);
|
||||
await relier.clickEmailFirst();
|
||||
// login_hint takes precedence over the signed-in user
|
||||
await relier.goto(`login_hint=${loginHintEmail}`);
|
||||
await relier.clickEmailFirst();
|
||||
|
||||
// Email is prefilled
|
||||
await expect(await login.getPrefilledEmail()).toEqual(loginHintEmail);
|
||||
expect(await login.signInPasswordHeader()).toEqual(true);
|
||||
// Email is prefilled
|
||||
await expect(await login.getPrefilledEmail()).toEqual(loginHintEmail);
|
||||
expect(await login.signInPasswordHeader()).toEqual(true);
|
||||
|
||||
await login.useDifferentAccountLink();
|
||||
await login.useDifferentAccountLink();
|
||||
|
||||
// Email first page has email input prefilled
|
||||
await expect(await login.getEmailInput()).toEqual(loginHintEmail);
|
||||
// Email first page has email input prefilled
|
||||
await expect(await login.getEmailInput()).toEqual(loginHintEmail);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -7,171 +7,173 @@ import { test, expect } from '../../lib/fixtures/standard';
|
|||
let email;
|
||||
const password = 'passwordzxcv';
|
||||
|
||||
test.describe('oauth permissions for trusted reliers - sign up', () => {
|
||||
test.beforeEach(async ({ pages: { login } }) => {
|
||||
test.slow();
|
||||
email = login.createEmail();
|
||||
await login.clearCache();
|
||||
});
|
||||
test.describe('severity-1 #smoke', () => {
|
||||
test.describe('oauth permissions for trusted reliers - sign up', () => {
|
||||
test.beforeEach(async ({ pages: { login } }) => {
|
||||
test.slow();
|
||||
email = login.createEmail();
|
||||
await login.clearCache();
|
||||
});
|
||||
|
||||
test.afterEach(async ({ target }) => {
|
||||
if (email) {
|
||||
// Cleanup any accounts created during the test
|
||||
try {
|
||||
await target.auth.accountDestroy(email, password);
|
||||
} catch (e) {
|
||||
// Handle the error here
|
||||
console.error('An error occurred during account cleanup:', e);
|
||||
// Optionally, rethrow the error to propagate it further
|
||||
throw e;
|
||||
test.afterEach(async ({ target }) => {
|
||||
if (email) {
|
||||
// Cleanup any accounts created during the test
|
||||
try {
|
||||
await target.auth.accountDestroy(email, password);
|
||||
} catch (e) {
|
||||
// Handle the error here
|
||||
console.error('An error occurred during account cleanup:', e);
|
||||
// Optionally, rethrow the error to propagate it further
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
test('signup without `prompt=consent`', async ({
|
||||
pages: { login, relier },
|
||||
}) => {
|
||||
await relier.goto();
|
||||
await relier.clickEmailFirst();
|
||||
await login.fillOutFirstSignUp(email, password, { verify: false });
|
||||
|
||||
//no permissions asked for, straight to confirm
|
||||
await login.waitForSignUpCodeHeader();
|
||||
});
|
||||
|
||||
test('signup with `prompt=consent`', async ({
|
||||
target,
|
||||
page,
|
||||
pages: { login, relier },
|
||||
}) => {
|
||||
const query = { prompt: 'consent' };
|
||||
const queryParam = new URLSearchParams(query);
|
||||
await page.goto(`${target.relierUrl}/?${queryParam.toString()}`, {
|
||||
waitUntil: 'load',
|
||||
});
|
||||
await relier.clickEmailFirst();
|
||||
await login.fillOutFirstSignUp(email, password, { verify: false });
|
||||
|
||||
//Verify permissions header
|
||||
expect(await login.permissionsHeader()).toBe(true);
|
||||
await login.acceptOauthPermissions();
|
||||
test('signup without `prompt=consent`', async ({
|
||||
pages: { login, relier },
|
||||
}) => {
|
||||
await relier.goto();
|
||||
await relier.clickEmailFirst();
|
||||
await login.fillOutFirstSignUp(email, password, { verify: false });
|
||||
|
||||
//Verify sign up code header
|
||||
await login.waitForSignUpCodeHeader();
|
||||
});
|
||||
});
|
||||
|
||||
test.describe('oauth permissions for trusted reliers - sign in', () => {
|
||||
test.beforeEach(async ({ pages: { login } }) => {
|
||||
test.slow();
|
||||
await login.clearCache();
|
||||
});
|
||||
|
||||
test('signin without `prompt=consent`', async ({
|
||||
credentials,
|
||||
pages: { login, relier },
|
||||
}) => {
|
||||
await relier.goto();
|
||||
await relier.clickEmailFirst();
|
||||
await login.fillOutEmailFirstSignIn(
|
||||
credentials.email,
|
||||
credentials.password
|
||||
);
|
||||
|
||||
//Verify logged in to relier
|
||||
expect(await relier.isLoggedIn()).toBe(true);
|
||||
});
|
||||
|
||||
test('signin with `prompt=consent`', async ({
|
||||
target,
|
||||
page,
|
||||
credentials,
|
||||
pages: { login, relier },
|
||||
}) => {
|
||||
const query = { prompt: 'consent' };
|
||||
const queryParam = new URLSearchParams(query);
|
||||
await page.goto(`${target.relierUrl}/?${queryParam.toString()}`, {
|
||||
waitUntil: 'load',
|
||||
});
|
||||
await relier.clickEmailFirst();
|
||||
await login.fillOutEmailFirstSignIn(
|
||||
credentials.email,
|
||||
credentials.password
|
||||
);
|
||||
|
||||
//Verify permissions header
|
||||
expect(await login.permissionsHeader()).toBe(true);
|
||||
await login.acceptOauthPermissions();
|
||||
|
||||
//Verify logged in to relier
|
||||
expect(await relier.isLoggedIn()).toBe(true);
|
||||
});
|
||||
|
||||
test('signin without `prompt=consent`, then re-signin with `prompt=consent`', async ({
|
||||
target,
|
||||
page,
|
||||
credentials,
|
||||
pages: { login, relier },
|
||||
}) => {
|
||||
await relier.goto();
|
||||
await relier.clickEmailFirst();
|
||||
await login.fillOutEmailFirstSignIn(
|
||||
credentials.email,
|
||||
credentials.password
|
||||
);
|
||||
|
||||
//Verify logged in to relier
|
||||
expect(await relier.isLoggedIn()).toBe(true);
|
||||
await relier.signOut();
|
||||
const query = { prompt: 'consent' };
|
||||
const queryParam = new URLSearchParams(query);
|
||||
await page.goto(`${target.relierUrl}/?${queryParam.toString()}`, {
|
||||
waitUntil: 'load',
|
||||
});
|
||||
await relier.clickEmailFirst();
|
||||
await login.clickSignIn();
|
||||
|
||||
//Verify permissions header
|
||||
expect(await login.permissionsHeader()).toBe(true);
|
||||
await login.acceptOauthPermissions();
|
||||
|
||||
//Verify logged in to relier
|
||||
expect(await relier.isLoggedIn()).toBe(true);
|
||||
});
|
||||
|
||||
test('force_auth without `prompt=consent`', async ({
|
||||
credentials,
|
||||
pages: { login, relier },
|
||||
}) => {
|
||||
await relier.goto(`email=${credentials.email}`);
|
||||
await relier.clickForceAuth();
|
||||
await login.setPassword(credentials.password);
|
||||
await login.submit();
|
||||
|
||||
//Verify logged in to relier
|
||||
expect(await relier.isLoggedIn()).toBe(true);
|
||||
});
|
||||
|
||||
test('force_auth with `prompt=consent`', async ({
|
||||
target,
|
||||
page,
|
||||
credentials,
|
||||
pages: { login, relier },
|
||||
}) => {
|
||||
const query = new URLSearchParams({
|
||||
prompt: 'consent',
|
||||
email: credentials.email,
|
||||
});
|
||||
await page.goto(`${target.relierUrl}/?${query.toString()}`);
|
||||
await relier.clickForceAuth();
|
||||
await login.setPassword(credentials.password);
|
||||
await login.submit();
|
||||
|
||||
//Verify permissions header
|
||||
expect(await login.permissionsHeader()).toBe(true);
|
||||
await login.acceptOauthPermissions();
|
||||
|
||||
//Verify logged in to relier
|
||||
expect(await relier.isLoggedIn()).toBe(true);
|
||||
//no permissions asked for, straight to confirm
|
||||
await login.waitForSignUpCodeHeader();
|
||||
});
|
||||
|
||||
test('signup with `prompt=consent`', async ({
|
||||
target,
|
||||
page,
|
||||
pages: { login, relier },
|
||||
}) => {
|
||||
const query = { prompt: 'consent' };
|
||||
const queryParam = new URLSearchParams(query);
|
||||
await page.goto(`${target.relierUrl}/?${queryParam.toString()}`, {
|
||||
waitUntil: 'load',
|
||||
});
|
||||
await relier.clickEmailFirst();
|
||||
await login.fillOutFirstSignUp(email, password, { verify: false });
|
||||
|
||||
//Verify permissions header
|
||||
expect(await login.permissionsHeader()).toBe(true);
|
||||
await login.acceptOauthPermissions();
|
||||
|
||||
//Verify sign up code header
|
||||
await login.waitForSignUpCodeHeader();
|
||||
});
|
||||
});
|
||||
|
||||
test.describe('oauth permissions for trusted reliers - sign in', () => {
|
||||
test.beforeEach(async ({ pages: { login } }) => {
|
||||
test.slow();
|
||||
await login.clearCache();
|
||||
});
|
||||
|
||||
test('signin without `prompt=consent`', async ({
|
||||
credentials,
|
||||
pages: { login, relier },
|
||||
}) => {
|
||||
await relier.goto();
|
||||
await relier.clickEmailFirst();
|
||||
await login.fillOutEmailFirstSignIn(
|
||||
credentials.email,
|
||||
credentials.password
|
||||
);
|
||||
|
||||
//Verify logged in to relier
|
||||
expect(await relier.isLoggedIn()).toBe(true);
|
||||
});
|
||||
|
||||
test('signin with `prompt=consent`', async ({
|
||||
target,
|
||||
page,
|
||||
credentials,
|
||||
pages: { login, relier },
|
||||
}) => {
|
||||
const query = { prompt: 'consent' };
|
||||
const queryParam = new URLSearchParams(query);
|
||||
await page.goto(`${target.relierUrl}/?${queryParam.toString()}`, {
|
||||
waitUntil: 'load',
|
||||
});
|
||||
await relier.clickEmailFirst();
|
||||
await login.fillOutEmailFirstSignIn(
|
||||
credentials.email,
|
||||
credentials.password
|
||||
);
|
||||
|
||||
//Verify permissions header
|
||||
expect(await login.permissionsHeader()).toBe(true);
|
||||
await login.acceptOauthPermissions();
|
||||
|
||||
//Verify logged in to relier
|
||||
expect(await relier.isLoggedIn()).toBe(true);
|
||||
});
|
||||
|
||||
test('signin without `prompt=consent`, then re-signin with `prompt=consent`', async ({
|
||||
target,
|
||||
page,
|
||||
credentials,
|
||||
pages: { login, relier },
|
||||
}) => {
|
||||
await relier.goto();
|
||||
await relier.clickEmailFirst();
|
||||
await login.fillOutEmailFirstSignIn(
|
||||
credentials.email,
|
||||
credentials.password
|
||||
);
|
||||
|
||||
//Verify logged in to relier
|
||||
expect(await relier.isLoggedIn()).toBe(true);
|
||||
await relier.signOut();
|
||||
const query = { prompt: 'consent' };
|
||||
const queryParam = new URLSearchParams(query);
|
||||
await page.goto(`${target.relierUrl}/?${queryParam.toString()}`, {
|
||||
waitUntil: 'load',
|
||||
});
|
||||
await relier.clickEmailFirst();
|
||||
await login.clickSignIn();
|
||||
|
||||
//Verify permissions header
|
||||
expect(await login.permissionsHeader()).toBe(true);
|
||||
await login.acceptOauthPermissions();
|
||||
|
||||
//Verify logged in to relier
|
||||
expect(await relier.isLoggedIn()).toBe(true);
|
||||
});
|
||||
|
||||
test('force_auth without `prompt=consent`', async ({
|
||||
credentials,
|
||||
pages: { login, relier },
|
||||
}) => {
|
||||
await relier.goto(`email=${credentials.email}`);
|
||||
await relier.clickForceAuth();
|
||||
await login.setPassword(credentials.password);
|
||||
await login.submit();
|
||||
|
||||
//Verify logged in to relier
|
||||
expect(await relier.isLoggedIn()).toBe(true);
|
||||
});
|
||||
|
||||
test('force_auth with `prompt=consent`', async ({
|
||||
target,
|
||||
page,
|
||||
credentials,
|
||||
pages: { login, relier },
|
||||
}) => {
|
||||
const query = new URLSearchParams({
|
||||
prompt: 'consent',
|
||||
email: credentials.email,
|
||||
});
|
||||
await page.goto(`${target.relierUrl}/?${query.toString()}`);
|
||||
await relier.clickForceAuth();
|
||||
await login.setPassword(credentials.password);
|
||||
await login.submit();
|
||||
|
||||
//Verify permissions header
|
||||
expect(await login.permissionsHeader()).toBe(true);
|
||||
await login.acceptOauthPermissions();
|
||||
|
||||
//Verify logged in to relier
|
||||
expect(await relier.isLoggedIn()).toBe(true);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -7,258 +7,261 @@ import { test, expect } from '../../lib/fixtures/standard';
|
|||
let email;
|
||||
const password = 'passwordzxcv';
|
||||
|
||||
test.describe('oauth prompt none', () => {
|
||||
test.beforeEach(async ({ pages: { login } }, { project }) => {
|
||||
test.slow();
|
||||
test.describe('severity-1 #smoke', () => {
|
||||
test.describe('oauth prompt none', () => {
|
||||
test.beforeEach(async ({ pages: { login } }, { project }) => {
|
||||
test.slow();
|
||||
|
||||
//Epic Fxa-7861 filed for the work to add plans in prod
|
||||
test.skip(
|
||||
project.name === 'production',
|
||||
'test plan not yet available in prod'
|
||||
);
|
||||
email = login.createEmail();
|
||||
await login.clearCache();
|
||||
//Epic Fxa-7861 filed for the work to add plans in prod
|
||||
test.skip(
|
||||
project.name === 'production',
|
||||
'test plan not yet available in prod'
|
||||
);
|
||||
email = login.createEmail();
|
||||
await login.clearCache();
|
||||
});
|
||||
|
||||
test('fails if no user logged in', async ({
|
||||
page,
|
||||
target,
|
||||
pages: { relier },
|
||||
}) => {
|
||||
const query = new URLSearchParams({
|
||||
login_hint: email,
|
||||
return_on_error: 'false',
|
||||
});
|
||||
await page.goto(`${target.relierUrl}/?${query.toString()}`);
|
||||
await relier.signInPromptNone();
|
||||
|
||||
//Verify error message
|
||||
expect(await relier.promptNoneError()).toContain('User is not signed in');
|
||||
});
|
||||
|
||||
test('fails RP that is not allowed', async ({ page, pages: { relier } }, {
|
||||
project,
|
||||
}) => {
|
||||
test.skip(
|
||||
project.name !== 'local',
|
||||
'we dont have an untrusted oauth for stage and prod'
|
||||
);
|
||||
const query = new URLSearchParams({
|
||||
login_hint: email,
|
||||
return_on_error: 'false',
|
||||
});
|
||||
await page.goto(`http://localhost:10139` + `/?${query.toString()}`);
|
||||
await relier.signInPromptNone();
|
||||
|
||||
//Verify error message
|
||||
expect(await relier.promptNoneError()).toContain(
|
||||
'prompt=none is not enabled for this client'
|
||||
);
|
||||
});
|
||||
|
||||
test('fails if requesting keys', async ({
|
||||
page,
|
||||
target,
|
||||
pages: { relier },
|
||||
}) => {
|
||||
const query = new URLSearchParams({
|
||||
client_id: '7f368c6886429f19', // eslint-disable-line camelcase
|
||||
forceUA:
|
||||
'Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Mobile Safari/537.36',
|
||||
// eslint-disable-next-line camelcase
|
||||
keys_jwk:
|
||||
'eyJrdHkiOiJFQyIsImtpZCI6Im9DNGFudFBBSFZRX1pmQ09RRUYycTRaQlZYblVNZ2xISGpVRzdtSjZHOEEiLCJjcnYiOi' +
|
||||
'JQLTI1NiIsIngiOiJDeUpUSjVwbUNZb2lQQnVWOTk1UjNvNTFLZVBMaEg1Y3JaQlkwbXNxTDk0IiwieSI6IkJCWDhfcFVZeHpTaldsdX' +
|
||||
'U5MFdPTVZwamIzTlpVRDAyN0xwcC04RW9vckEifQ',
|
||||
login_hint: email, // eslint-disable-line camelcase
|
||||
redirect_uri:
|
||||
'https://mozilla.github.io/notes/fxa/android-redirect.html', // eslint-disable-line camelcase
|
||||
scope: 'profile https://identity.mozilla.com/apps/notes',
|
||||
return_on_error: 'false',
|
||||
});
|
||||
await page.goto(`${target.relierUrl}/?${query.toString()}`);
|
||||
await relier.signInPromptNone();
|
||||
|
||||
//Verify error message
|
||||
expect(await relier.promptNoneError()).toContain(
|
||||
'prompt=none cannot be used when requesting keys'
|
||||
);
|
||||
});
|
||||
|
||||
test('fails if session is no longer valid', async ({
|
||||
page,
|
||||
target,
|
||||
pages: { relier, login },
|
||||
}) => {
|
||||
await target.auth.signUp(email, password, {
|
||||
lang: 'en',
|
||||
preVerified: 'true',
|
||||
});
|
||||
await page.goto(target.contentServerUrl, {
|
||||
waitUntil: 'load',
|
||||
});
|
||||
await login.fillOutEmailFirstSignIn(email, password);
|
||||
|
||||
//Verify logged in on Settings page
|
||||
expect(await login.isUserLoggedIn()).toBe(true);
|
||||
await target.auth.accountDestroy(email, password);
|
||||
|
||||
const query = new URLSearchParams({
|
||||
login_hint: email,
|
||||
return_on_error: 'false',
|
||||
});
|
||||
await page.goto(`${target.relierUrl}/?${query.toString()}`);
|
||||
await relier.signInPromptNone();
|
||||
|
||||
//Verify error message
|
||||
expect(await relier.promptNoneError()).toContain('User is not signed in');
|
||||
});
|
||||
|
||||
test('fails if account is not verified', async ({
|
||||
page,
|
||||
target,
|
||||
pages: { relier, login },
|
||||
}) => {
|
||||
await target.auth.signUp(email, password, {
|
||||
lang: 'en',
|
||||
preVerified: 'false',
|
||||
});
|
||||
await page.goto(target.contentServerUrl, {
|
||||
waitUntil: 'load',
|
||||
});
|
||||
await login.fillOutEmailFirstSignIn(email, password);
|
||||
|
||||
//Verify sign up code header
|
||||
await login.waitForSignUpCodeHeader();
|
||||
|
||||
const query = new URLSearchParams({
|
||||
login_hint: email,
|
||||
return_on_error: 'false',
|
||||
});
|
||||
await page.goto(`${target.relierUrl}/?${query.toString()}`);
|
||||
|
||||
await relier.signInPromptNone();
|
||||
|
||||
//Verify error message
|
||||
expect(await relier.promptNoneError()).toContain(
|
||||
'Unverified user or session'
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
test('fails if no user logged in', async ({
|
||||
page,
|
||||
target,
|
||||
pages: { relier },
|
||||
}) => {
|
||||
const query = new URLSearchParams({
|
||||
login_hint: email,
|
||||
return_on_error: 'false',
|
||||
test.describe('oauth prompt none with emails', () => {
|
||||
test.beforeEach(async ({ pages: { login } }, { project }) => {
|
||||
test.slow();
|
||||
|
||||
//Epic Fxa-7861 filed for the work to add plans in prod
|
||||
test.skip(
|
||||
project.name === 'production',
|
||||
'test plan not yet available in prod'
|
||||
);
|
||||
email = login.createEmail();
|
||||
await login.clearCache();
|
||||
});
|
||||
await page.goto(`${target.relierUrl}/?${query.toString()}`);
|
||||
await relier.signInPromptNone();
|
||||
|
||||
//Verify error message
|
||||
expect(await relier.promptNoneError()).toContain('User is not signed in');
|
||||
});
|
||||
|
||||
test('fails RP that is not allowed', async ({ page, pages: { relier } }, {
|
||||
project,
|
||||
}) => {
|
||||
test.skip(
|
||||
project.name !== 'local',
|
||||
'we dont have an untrusted oauth for stage and prod'
|
||||
);
|
||||
const query = new URLSearchParams({
|
||||
login_hint: email,
|
||||
return_on_error: 'false',
|
||||
});
|
||||
await page.goto(`http://localhost:10139` + `/?${query.toString()}`);
|
||||
await relier.signInPromptNone();
|
||||
|
||||
//Verify error message
|
||||
expect(await relier.promptNoneError()).toContain(
|
||||
'prompt=none is not enabled for this client'
|
||||
);
|
||||
});
|
||||
|
||||
test('fails if requesting keys', async ({
|
||||
page,
|
||||
target,
|
||||
pages: { relier },
|
||||
}) => {
|
||||
const query = new URLSearchParams({
|
||||
client_id: '7f368c6886429f19', // eslint-disable-line camelcase
|
||||
forceUA:
|
||||
'Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Mobile Safari/537.36',
|
||||
// eslint-disable-next-line camelcase
|
||||
keys_jwk:
|
||||
'eyJrdHkiOiJFQyIsImtpZCI6Im9DNGFudFBBSFZRX1pmQ09RRUYycTRaQlZYblVNZ2xISGpVRzdtSjZHOEEiLCJjcnYiOi' +
|
||||
'JQLTI1NiIsIngiOiJDeUpUSjVwbUNZb2lQQnVWOTk1UjNvNTFLZVBMaEg1Y3JaQlkwbXNxTDk0IiwieSI6IkJCWDhfcFVZeHpTaldsdX' +
|
||||
'U5MFdPTVZwamIzTlpVRDAyN0xwcC04RW9vckEifQ',
|
||||
login_hint: email, // eslint-disable-line camelcase
|
||||
redirect_uri: 'https://mozilla.github.io/notes/fxa/android-redirect.html', // eslint-disable-line camelcase
|
||||
scope: 'profile https://identity.mozilla.com/apps/notes',
|
||||
return_on_error: 'false',
|
||||
});
|
||||
await page.goto(`${target.relierUrl}/?${query.toString()}`);
|
||||
await relier.signInPromptNone();
|
||||
|
||||
//Verify error message
|
||||
expect(await relier.promptNoneError()).toContain(
|
||||
'prompt=none cannot be used when requesting keys'
|
||||
);
|
||||
});
|
||||
|
||||
test('fails if session is no longer valid', async ({
|
||||
page,
|
||||
target,
|
||||
pages: { relier, login },
|
||||
}) => {
|
||||
await target.auth.signUp(email, password, {
|
||||
lang: 'en',
|
||||
preVerified: 'true',
|
||||
});
|
||||
await page.goto(target.contentServerUrl, {
|
||||
waitUntil: 'load',
|
||||
});
|
||||
await login.fillOutEmailFirstSignIn(email, password);
|
||||
|
||||
//Verify logged in on Settings page
|
||||
expect(await login.isUserLoggedIn()).toBe(true);
|
||||
await target.auth.accountDestroy(email, password);
|
||||
|
||||
const query = new URLSearchParams({
|
||||
login_hint: email,
|
||||
return_on_error: 'false',
|
||||
});
|
||||
await page.goto(`${target.relierUrl}/?${query.toString()}`);
|
||||
await relier.signInPromptNone();
|
||||
|
||||
//Verify error message
|
||||
expect(await relier.promptNoneError()).toContain('User is not signed in');
|
||||
});
|
||||
|
||||
test('fails if account is not verified', async ({
|
||||
page,
|
||||
target,
|
||||
pages: { relier, login },
|
||||
}) => {
|
||||
await target.auth.signUp(email, password, {
|
||||
lang: 'en',
|
||||
preVerified: 'false',
|
||||
});
|
||||
await page.goto(target.contentServerUrl, {
|
||||
waitUntil: 'load',
|
||||
});
|
||||
await login.fillOutEmailFirstSignIn(email, password);
|
||||
|
||||
//Verify sign up code header
|
||||
await login.waitForSignUpCodeHeader();
|
||||
|
||||
const query = new URLSearchParams({
|
||||
login_hint: email,
|
||||
return_on_error: 'false',
|
||||
});
|
||||
await page.goto(`${target.relierUrl}/?${query.toString()}`);
|
||||
|
||||
await relier.signInPromptNone();
|
||||
|
||||
//Verify error message
|
||||
expect(await relier.promptNoneError()).toContain(
|
||||
'Unverified user or session'
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
test.describe('oauth prompt none with emails', () => {
|
||||
test.beforeEach(async ({ pages: { login } }, { project }) => {
|
||||
test.slow();
|
||||
|
||||
//Epic Fxa-7861 filed for the work to add plans in prod
|
||||
test.skip(
|
||||
project.name === 'production',
|
||||
'test plan not yet available in prod'
|
||||
);
|
||||
email = login.createEmail();
|
||||
await login.clearCache();
|
||||
});
|
||||
|
||||
test.afterEach(async ({ target }) => {
|
||||
if (email) {
|
||||
// Cleanup any accounts created during the test
|
||||
try {
|
||||
await target.auth.accountDestroy(email, password);
|
||||
} catch (e) {
|
||||
// Handle the error here
|
||||
console.error('An error occurred during account cleanup:', e);
|
||||
// Optionally, rethrow the error to propagate it further
|
||||
throw e;
|
||||
test.afterEach(async ({ target }) => {
|
||||
if (email) {
|
||||
// Cleanup any accounts created during the test
|
||||
try {
|
||||
await target.auth.accountDestroy(email, password);
|
||||
} catch (e) {
|
||||
// Handle the error here
|
||||
console.error('An error occurred during account cleanup:', e);
|
||||
// Optionally, rethrow the error to propagate it further
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
test('fails if no login_hint', async ({
|
||||
page,
|
||||
target,
|
||||
pages: { relier, login },
|
||||
}) => {
|
||||
await target.auth.signUp(email, password, {
|
||||
lang: 'en',
|
||||
preVerified: 'true',
|
||||
});
|
||||
await page.goto(target.contentServerUrl, {
|
||||
waitUntil: 'load',
|
||||
|
||||
test('fails if no login_hint', async ({
|
||||
page,
|
||||
target,
|
||||
pages: { relier, login },
|
||||
}) => {
|
||||
await target.auth.signUp(email, password, {
|
||||
lang: 'en',
|
||||
preVerified: 'true',
|
||||
});
|
||||
await page.goto(target.contentServerUrl, {
|
||||
waitUntil: 'load',
|
||||
});
|
||||
await login.fillOutEmailFirstSignIn(email, password);
|
||||
|
||||
//Verify logged in on Settings page
|
||||
expect(await login.isUserLoggedIn()).toBe(true);
|
||||
|
||||
const query = new URLSearchParams({
|
||||
return_on_error: 'false',
|
||||
});
|
||||
await page.goto(`${target.relierUrl}/?${query.toString()}`);
|
||||
|
||||
await relier.signInPromptNone();
|
||||
|
||||
//Verify error message
|
||||
expect(await relier.promptNoneError()).toContain(
|
||||
'Missing OAuth parameter: login_hint'
|
||||
);
|
||||
});
|
||||
await login.fillOutEmailFirstSignIn(email, password);
|
||||
|
||||
//Verify logged in on Settings page
|
||||
expect(await login.isUserLoggedIn()).toBe(true);
|
||||
test('fails if login_hint is different to logged in user', async ({
|
||||
page,
|
||||
target,
|
||||
pages: { relier, login },
|
||||
}) => {
|
||||
await target.auth.signUp(email, password, {
|
||||
lang: 'en',
|
||||
preVerified: 'true',
|
||||
});
|
||||
await page.goto(target.contentServerUrl, {
|
||||
waitUntil: 'load',
|
||||
});
|
||||
await login.fillOutEmailFirstSignIn(email, password);
|
||||
|
||||
const query = new URLSearchParams({
|
||||
return_on_error: 'false',
|
||||
//Verify logged in on Settings page
|
||||
expect(await login.isUserLoggedIn()).toBe(true);
|
||||
|
||||
const query = new URLSearchParams({
|
||||
login_hint: login.createEmail(),
|
||||
return_on_error: 'false',
|
||||
});
|
||||
await page.goto(`${target.relierUrl}/?${query.toString()}`);
|
||||
|
||||
await relier.signInPromptNone();
|
||||
|
||||
//Verify error message
|
||||
expect(await relier.promptNoneError()).toContain(
|
||||
'A different user is signed in'
|
||||
);
|
||||
});
|
||||
await page.goto(`${target.relierUrl}/?${query.toString()}`);
|
||||
|
||||
await relier.signInPromptNone();
|
||||
test('succeeds if login_hint same as logged in user', async ({
|
||||
page,
|
||||
target,
|
||||
pages: { relier, login },
|
||||
}) => {
|
||||
await target.auth.signUp(email, password, {
|
||||
lang: 'en',
|
||||
preVerified: 'true',
|
||||
});
|
||||
await page.goto(target.contentServerUrl, {
|
||||
waitUntil: 'load',
|
||||
});
|
||||
await login.fillOutEmailFirstSignIn(email, password);
|
||||
|
||||
//Verify error message
|
||||
expect(await relier.promptNoneError()).toContain(
|
||||
'Missing OAuth parameter: login_hint'
|
||||
);
|
||||
});
|
||||
//Verify logged in on Settings page
|
||||
expect(await login.isUserLoggedIn()).toBe(true);
|
||||
|
||||
test('fails if login_hint is different to logged in user', async ({
|
||||
page,
|
||||
target,
|
||||
pages: { relier, login },
|
||||
}) => {
|
||||
await target.auth.signUp(email, password, {
|
||||
lang: 'en',
|
||||
preVerified: 'true',
|
||||
const query = new URLSearchParams({
|
||||
login_hint: email,
|
||||
return_on_error: 'false',
|
||||
});
|
||||
await page.goto(`${target.relierUrl}/?${query.toString()}`);
|
||||
|
||||
await relier.signInPromptNone();
|
||||
|
||||
//Verify logged in to relier
|
||||
expect(await relier.isLoggedIn()).toBe(true);
|
||||
});
|
||||
await page.goto(target.contentServerUrl, {
|
||||
waitUntil: 'load',
|
||||
});
|
||||
await login.fillOutEmailFirstSignIn(email, password);
|
||||
|
||||
//Verify logged in on Settings page
|
||||
expect(await login.isUserLoggedIn()).toBe(true);
|
||||
|
||||
const query = new URLSearchParams({
|
||||
login_hint: login.createEmail(),
|
||||
return_on_error: 'false',
|
||||
});
|
||||
await page.goto(`${target.relierUrl}/?${query.toString()}`);
|
||||
|
||||
await relier.signInPromptNone();
|
||||
|
||||
//Verify error message
|
||||
expect(await relier.promptNoneError()).toContain(
|
||||
'A different user is signed in'
|
||||
);
|
||||
});
|
||||
|
||||
test('succeeds if login_hint same as logged in user', async ({
|
||||
page,
|
||||
target,
|
||||
pages: { relier, login },
|
||||
}) => {
|
||||
await target.auth.signUp(email, password, {
|
||||
lang: 'en',
|
||||
preVerified: 'true',
|
||||
});
|
||||
await page.goto(target.contentServerUrl, {
|
||||
waitUntil: 'load',
|
||||
});
|
||||
await login.fillOutEmailFirstSignIn(email, password);
|
||||
|
||||
//Verify logged in on Settings page
|
||||
expect(await login.isUserLoggedIn()).toBe(true);
|
||||
|
||||
const query = new URLSearchParams({
|
||||
login_hint: email,
|
||||
return_on_error: 'false',
|
||||
});
|
||||
await page.goto(`${target.relierUrl}/?${query.toString()}`);
|
||||
|
||||
await relier.signInPromptNone();
|
||||
|
||||
//Verify logged in to relier
|
||||
expect(await relier.isLoggedIn()).toBe(true);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -5,41 +5,43 @@
|
|||
import { test, expect } from '../../lib/fixtures/standard';
|
||||
import { EmailHeader, EmailType } from '../../lib/email';
|
||||
|
||||
test.describe('oauth reset password', () => {
|
||||
test.beforeEach(async ({ pages: { configPage } }) => {
|
||||
test.slow();
|
||||
test.describe('severity-1 #smoke', () => {
|
||||
test.describe('oauth reset password', () => {
|
||||
test.beforeEach(async ({ pages: { configPage } }) => {
|
||||
test.slow();
|
||||
|
||||
const config = await configPage.getConfig();
|
||||
test.skip(config.showReactApp.resetPasswordRoutes === true);
|
||||
test.skip(config.showReactApp.oauthRoutes === true);
|
||||
});
|
||||
const config = await configPage.getConfig();
|
||||
test.skip(config.showReactApp.resetPasswordRoutes === true);
|
||||
test.skip(config.showReactApp.oauthRoutes === true);
|
||||
});
|
||||
|
||||
test('reset password happy path', async ({
|
||||
target,
|
||||
page,
|
||||
credentials,
|
||||
pages: { login, relier, resetPassword },
|
||||
}) => {
|
||||
await relier.goto();
|
||||
await relier.clickEmailFirst();
|
||||
await login.setEmail(credentials.email);
|
||||
await login.submit();
|
||||
await login.clickForgotPassword();
|
||||
test('reset password happy path', async ({
|
||||
target,
|
||||
page,
|
||||
credentials,
|
||||
pages: { login, relier, resetPassword },
|
||||
}) => {
|
||||
await relier.goto();
|
||||
await relier.clickEmailFirst();
|
||||
await login.setEmail(credentials.email);
|
||||
await login.submit();
|
||||
await login.clickForgotPassword();
|
||||
|
||||
// Verify reset password header
|
||||
await resetPassword.resetPasswordHeader();
|
||||
// Verify reset password header
|
||||
await resetPassword.resetPasswordHeader();
|
||||
|
||||
await resetPassword.fillOutResetPassword(credentials.email);
|
||||
await resetPassword.fillOutResetPassword(credentials.email);
|
||||
|
||||
const link = await target.email.waitForEmail(
|
||||
credentials.email,
|
||||
EmailType.recovery,
|
||||
EmailHeader.link
|
||||
);
|
||||
await page.goto(link);
|
||||
await resetPassword.resetNewPassword(credentials.password);
|
||||
const link = await target.email.waitForEmail(
|
||||
credentials.email,
|
||||
EmailType.recovery,
|
||||
EmailHeader.link
|
||||
);
|
||||
await page.goto(link);
|
||||
await resetPassword.resetNewPassword(credentials.password);
|
||||
|
||||
// Verify logged in
|
||||
expect(await relier.isLoggedIn()).toBe(true);
|
||||
// Verify logged in
|
||||
expect(await relier.isLoggedIn()).toBe(true);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -1,3 +1,7 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
import { test, expect } from '../../lib/fixtures/standard';
|
||||
|
||||
const PASSWORD = 'passwordzxcv';
|
||||
|
|
|
@ -8,82 +8,84 @@ let email;
|
|||
let bouncedEmail;
|
||||
const password = 'passwordzxcv';
|
||||
|
||||
test.describe('Oauth sign up', () => {
|
||||
test.beforeEach(async ({ pages: { login } }) => {
|
||||
test.slow();
|
||||
email = login.createEmail();
|
||||
bouncedEmail = login.createEmail('bounced{id}');
|
||||
await login.clearCache();
|
||||
test.describe('severity-1 #smoke', () => {
|
||||
test.describe('Oauth sign up', () => {
|
||||
test.beforeEach(async ({ pages: { login } }) => {
|
||||
test.slow();
|
||||
email = login.createEmail();
|
||||
bouncedEmail = login.createEmail('bounced{id}');
|
||||
await login.clearCache();
|
||||
});
|
||||
|
||||
test.afterEach(async ({ target }) => {
|
||||
if (email) {
|
||||
// Cleanup any accounts created during the test
|
||||
await target.auth.accountDestroy(email, password);
|
||||
}
|
||||
});
|
||||
|
||||
test('sign up', async ({ pages: { login, relier } }) => {
|
||||
await relier.goto();
|
||||
await relier.clickEmailFirst();
|
||||
await login.fillOutFirstSignUp(email, password, { verify: false });
|
||||
|
||||
//Verify sign up code header
|
||||
await login.waitForSignUpCodeHeader();
|
||||
|
||||
await login.fillOutSignUpCode(email);
|
||||
|
||||
//Verify logged in on relier page
|
||||
expect(await relier.isLoggedIn()).toBe(true);
|
||||
});
|
||||
|
||||
test('signup, bounce email, allow user to restart flow but force a different email', async ({
|
||||
target,
|
||||
pages: { login, relier },
|
||||
}) => {
|
||||
const client = await login.getFxaClient(target);
|
||||
|
||||
await relier.goto();
|
||||
await relier.clickEmailFirst();
|
||||
await login.fillOutFirstSignUp(bouncedEmail, password, { verify: false });
|
||||
|
||||
//Verify sign up code header
|
||||
await login.waitForSignUpCodeHeader();
|
||||
await client.accountDestroy(bouncedEmail, password);
|
||||
|
||||
//Verify error message
|
||||
expect(await login.getTooltipError()).toContain(
|
||||
'Your confirmation email was just returned. Mistyped email?'
|
||||
);
|
||||
|
||||
await login.clearEmailTextBox();
|
||||
await login.fillOutFirstSignUp(email, password, { verify: false });
|
||||
|
||||
//Verify sign up code header
|
||||
await login.waitForSignUpCodeHeader();
|
||||
await login.fillOutSignUpCode(email);
|
||||
|
||||
//Verify logged in on relier page
|
||||
expect(await relier.isLoggedIn()).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
test.afterEach(async ({ target }) => {
|
||||
if (email) {
|
||||
// Cleanup any accounts created during the test
|
||||
await target.auth.accountDestroy(email, password);
|
||||
}
|
||||
});
|
||||
test.describe('Oauth sign up success', () => {
|
||||
test.beforeEach(async ({ pages: { login } }) => {
|
||||
test.slow();
|
||||
await login.clearCache();
|
||||
});
|
||||
|
||||
test('sign up', async ({ pages: { login, relier } }) => {
|
||||
await relier.goto();
|
||||
await relier.clickEmailFirst();
|
||||
await login.fillOutFirstSignUp(email, password, { verify: false });
|
||||
test('a success screen is available', async ({
|
||||
target,
|
||||
page,
|
||||
pages: { relier },
|
||||
}) => {
|
||||
await page.goto(
|
||||
`${target.contentServerUrl}/oauth/success/dcdb5ae7add825d2`
|
||||
);
|
||||
|
||||
//Verify sign up code header
|
||||
await login.waitForSignUpCodeHeader();
|
||||
|
||||
await login.fillOutSignUpCode(email);
|
||||
|
||||
//Verify logged in on relier page
|
||||
expect(await relier.isLoggedIn()).toBe(true);
|
||||
});
|
||||
|
||||
test('signup, bounce email, allow user to restart flow but force a different email', async ({
|
||||
target,
|
||||
pages: { login, relier },
|
||||
}) => {
|
||||
const client = await login.getFxaClient(target);
|
||||
|
||||
await relier.goto();
|
||||
await relier.clickEmailFirst();
|
||||
await login.fillOutFirstSignUp(bouncedEmail, password, { verify: false });
|
||||
|
||||
//Verify sign up code header
|
||||
await login.waitForSignUpCodeHeader();
|
||||
await client.accountDestroy(bouncedEmail, password);
|
||||
|
||||
//Verify error message
|
||||
expect(await login.getTooltipError()).toContain(
|
||||
'Your confirmation email was just returned. Mistyped email?'
|
||||
);
|
||||
|
||||
await login.clearEmailTextBox();
|
||||
await login.fillOutFirstSignUp(email, password, { verify: false });
|
||||
|
||||
//Verify sign up code header
|
||||
await login.waitForSignUpCodeHeader();
|
||||
await login.fillOutSignUpCode(email);
|
||||
|
||||
//Verify logged in on relier page
|
||||
expect(await relier.isLoggedIn()).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
test.describe('Oauth sign up success', () => {
|
||||
test.beforeEach(async ({ pages: { login } }) => {
|
||||
test.slow();
|
||||
await login.clearCache();
|
||||
});
|
||||
|
||||
test('a success screen is available', async ({
|
||||
target,
|
||||
page,
|
||||
pages: { relier },
|
||||
}) => {
|
||||
await page.goto(
|
||||
`${target.contentServerUrl}/oauth/success/dcdb5ae7add825d2`
|
||||
);
|
||||
|
||||
//Verify oauth success header
|
||||
expect(await relier.isOauthSuccessHeader()).toBe(true);
|
||||
//Verify oauth success header
|
||||
expect(await relier.isOauthSuccessHeader()).toBe(true);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -1,169 +1,182 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
import { test, expect } from '../../lib/fixtures/standard';
|
||||
|
||||
let email = '';
|
||||
const PASSWORD = 'passwordzxcv';
|
||||
|
||||
test.describe('OAuth signin', () => {
|
||||
test.beforeEach(({}, testInfo) => {
|
||||
test.slow(testInfo.project.name !== 'local', 'email delivery can be slow');
|
||||
});
|
||||
|
||||
test('verified', async ({ credentials, pages: { login, relier } }) => {
|
||||
await relier.goto();
|
||||
await relier.clickEmailFirst();
|
||||
await login.login(credentials.email, credentials.password);
|
||||
expect(await relier.isLoggedIn()).toBe(true);
|
||||
});
|
||||
|
||||
test('verified using a cached login', async ({
|
||||
credentials,
|
||||
pages: { login, relier },
|
||||
}) => {
|
||||
await relier.goto();
|
||||
await relier.clickEmailFirst();
|
||||
await login.login(credentials.email, credentials.password);
|
||||
expect(await relier.isLoggedIn()).toBe(true);
|
||||
|
||||
await relier.signOut();
|
||||
|
||||
// Attempt to sign back in
|
||||
await relier.clickEmailFirst();
|
||||
|
||||
// Email is prefilled
|
||||
await expect(await login.getPrefilledEmail()).toContain(credentials.email);
|
||||
expect(await login.isCachedLogin()).toBe(true);
|
||||
await login.submit();
|
||||
|
||||
expect(await relier.isLoggedIn()).toBe(true);
|
||||
});
|
||||
|
||||
test('verified using a cached expired login', async ({
|
||||
credentials,
|
||||
pages: { login, relier },
|
||||
}) => {
|
||||
await relier.goto();
|
||||
await relier.clickEmailFirst();
|
||||
await login.login(credentials.email, credentials.password);
|
||||
expect(await relier.isLoggedIn()).toBe(true);
|
||||
|
||||
await relier.signOut();
|
||||
|
||||
// Attempt to sign back in with cached user
|
||||
await relier.clickEmailFirst();
|
||||
|
||||
await expect(await login.getPrefilledEmail()).toContain(credentials.email);
|
||||
expect(await login.isCachedLogin()).toBe(true);
|
||||
await login.submit();
|
||||
await relier.signOut();
|
||||
|
||||
// Clear cache and try to login
|
||||
await login.clearCache();
|
||||
await relier.goto();
|
||||
await relier.clickEmailFirst();
|
||||
|
||||
// User will have to re-enter login information
|
||||
await login.login(credentials.email, credentials.password);
|
||||
expect(await relier.isLoggedIn()).toBe(true);
|
||||
});
|
||||
|
||||
test('unverified, acts like signup', async ({
|
||||
target,
|
||||
pages: { login, relier },
|
||||
}) => {
|
||||
// Create unverified account via backend
|
||||
email = login.createEmail();
|
||||
await target.auth.signUp(email, PASSWORD, {
|
||||
lang: 'en',
|
||||
preVerified: 'false',
|
||||
test.describe('severity-1 #smoke', () => {
|
||||
test.describe('OAuth signin', () => {
|
||||
test.beforeEach(({}, testInfo) => {
|
||||
test.slow(
|
||||
testInfo.project.name !== 'local',
|
||||
'email delivery can be slow'
|
||||
);
|
||||
});
|
||||
|
||||
await relier.goto();
|
||||
await relier.clickEmailFirst();
|
||||
await login.login(email, PASSWORD);
|
||||
test('verified', async ({ credentials, pages: { login, relier } }) => {
|
||||
await relier.goto();
|
||||
await relier.clickEmailFirst();
|
||||
await login.login(credentials.email, credentials.password);
|
||||
expect(await relier.isLoggedIn()).toBe(true);
|
||||
});
|
||||
|
||||
// User is shown confirm email page
|
||||
await login.fillOutSignInCode(email);
|
||||
test('verified using a cached login', async ({
|
||||
credentials,
|
||||
pages: { login, relier },
|
||||
}) => {
|
||||
await relier.goto();
|
||||
await relier.clickEmailFirst();
|
||||
await login.login(credentials.email, credentials.password);
|
||||
expect(await relier.isLoggedIn()).toBe(true);
|
||||
|
||||
expect(await relier.isLoggedIn()).toBe(true);
|
||||
});
|
||||
await relier.signOut();
|
||||
|
||||
test('unverified with a cached login', async ({
|
||||
pages: { login, relier },
|
||||
}) => {
|
||||
// Create unverified account
|
||||
email = login.createEmail();
|
||||
const password = 'passwordzxcv';
|
||||
// Attempt to sign back in
|
||||
await relier.clickEmailFirst();
|
||||
|
||||
await relier.goto();
|
||||
await relier.clickEmailFirst();
|
||||
// Email is prefilled
|
||||
await expect(await login.getPrefilledEmail()).toContain(
|
||||
credentials.email
|
||||
);
|
||||
expect(await login.isCachedLogin()).toBe(true);
|
||||
await login.submit();
|
||||
|
||||
// Dont register account and attempt to login via relier
|
||||
await login.fillOutFirstSignUp(email, password, { verify: false });
|
||||
expect(await relier.isLoggedIn()).toBe(true);
|
||||
});
|
||||
|
||||
await relier.goto();
|
||||
await relier.clickEmailFirst();
|
||||
test('verified using a cached expired login', async ({
|
||||
credentials,
|
||||
pages: { login, relier },
|
||||
}) => {
|
||||
await relier.goto();
|
||||
await relier.clickEmailFirst();
|
||||
await login.login(credentials.email, credentials.password);
|
||||
expect(await relier.isLoggedIn()).toBe(true);
|
||||
|
||||
// Cached user detected
|
||||
await expect(await login.getPrefilledEmail()).toContain(email);
|
||||
expect(await login.isCachedLogin()).toBe(true);
|
||||
await login.submit();
|
||||
await relier.signOut();
|
||||
|
||||
// Verify email and ensure user is redirected to relier
|
||||
await login.fillOutSignUpCode(email);
|
||||
// Attempt to sign back in with cached user
|
||||
await relier.clickEmailFirst();
|
||||
|
||||
expect(await relier.isLoggedIn()).toBe(true);
|
||||
});
|
||||
await expect(await login.getPrefilledEmail()).toContain(
|
||||
credentials.email
|
||||
);
|
||||
expect(await login.isCachedLogin()).toBe(true);
|
||||
await login.submit();
|
||||
await relier.signOut();
|
||||
|
||||
test('oauth endpoint chooses the right auth flows', async ({
|
||||
target,
|
||||
page,
|
||||
credentials,
|
||||
pages: { login, relier },
|
||||
}, { project }) => {
|
||||
test.slow(project.name !== 'local', 'email delivery can be slow');
|
||||
// Clear cache and try to login
|
||||
await login.clearCache();
|
||||
await relier.goto();
|
||||
await relier.clickEmailFirst();
|
||||
|
||||
// Create unverified account
|
||||
email = login.createEmail();
|
||||
// User will have to re-enter login information
|
||||
await login.login(credentials.email, credentials.password);
|
||||
expect(await relier.isLoggedIn()).toBe(true);
|
||||
});
|
||||
|
||||
await relier.goto();
|
||||
await relier.clickChooseFlow();
|
||||
await login.fillOutFirstSignUp(email, PASSWORD, { verify: false });
|
||||
test('unverified, acts like signup', async ({
|
||||
target,
|
||||
pages: { login, relier },
|
||||
}) => {
|
||||
// Create unverified account via backend
|
||||
email = login.createEmail();
|
||||
await target.auth.signUp(email, PASSWORD, {
|
||||
lang: 'en',
|
||||
preVerified: 'false',
|
||||
});
|
||||
|
||||
// go back to the OAuth app, the /oauth flow should
|
||||
// now suggest a cached login
|
||||
await relier.goto();
|
||||
await relier.clickChooseFlow();
|
||||
await relier.goto();
|
||||
await relier.clickEmailFirst();
|
||||
await login.login(email, PASSWORD);
|
||||
|
||||
// User shown signin enter password page
|
||||
expect(await login.signInPasswordHeader()).toEqual(true);
|
||||
});
|
||||
// User is shown confirm email page
|
||||
await login.fillOutSignInCode(email);
|
||||
|
||||
test('verified, blocked', async ({ target, pages: { login, relier } }) => {
|
||||
const blockedEmail = login.createEmail('blocked{id}');
|
||||
await target.createAccount(blockedEmail, PASSWORD);
|
||||
expect(await relier.isLoggedIn()).toBe(true);
|
||||
});
|
||||
|
||||
await relier.goto();
|
||||
await relier.clickEmailFirst();
|
||||
await login.login(blockedEmail, PASSWORD);
|
||||
test('unverified with a cached login', async ({
|
||||
pages: { login, relier },
|
||||
}) => {
|
||||
// Create unverified account
|
||||
email = login.createEmail();
|
||||
const password = 'passwordzxcv';
|
||||
|
||||
await login.unblock(blockedEmail);
|
||||
expect(await relier.isLoggedIn()).toBe(true);
|
||||
});
|
||||
await relier.goto();
|
||||
await relier.clickEmailFirst();
|
||||
|
||||
test('verified, blocked, incorrect password', async ({
|
||||
target,
|
||||
pages: { login, relier },
|
||||
}) => {
|
||||
const blockedEmail = login.createEmail('blocked{id}');
|
||||
await target.createAccount(blockedEmail, PASSWORD);
|
||||
// Dont register account and attempt to login via relier
|
||||
await login.fillOutFirstSignUp(email, password, { verify: false });
|
||||
|
||||
await relier.goto();
|
||||
await relier.clickEmailFirst();
|
||||
await login.login(blockedEmail, 'wrong password');
|
||||
await relier.goto();
|
||||
await relier.clickEmailFirst();
|
||||
|
||||
await login.unblock(blockedEmail);
|
||||
// Cached user detected
|
||||
await expect(await login.getPrefilledEmail()).toContain(email);
|
||||
expect(await login.isCachedLogin()).toBe(true);
|
||||
await login.submit();
|
||||
|
||||
// After filling in the unblock code, the user is prompted again to enter password
|
||||
expect(await login.signInPasswordHeader()).toEqual(true);
|
||||
// Verify email and ensure user is redirected to relier
|
||||
await login.fillOutSignUpCode(email);
|
||||
|
||||
expect(await relier.isLoggedIn()).toBe(true);
|
||||
});
|
||||
|
||||
test('oauth endpoint chooses the right auth flows', async ({
|
||||
target,
|
||||
page,
|
||||
credentials,
|
||||
pages: { login, relier },
|
||||
}, { project }) => {
|
||||
test.slow(project.name !== 'local', 'email delivery can be slow');
|
||||
|
||||
// Create unverified account
|
||||
email = login.createEmail();
|
||||
|
||||
await relier.goto();
|
||||
await relier.clickChooseFlow();
|
||||
await login.fillOutFirstSignUp(email, PASSWORD, { verify: false });
|
||||
|
||||
// go back to the OAuth app, the /oauth flow should
|
||||
// now suggest a cached login
|
||||
await relier.goto();
|
||||
await relier.clickChooseFlow();
|
||||
|
||||
// User shown signin enter password page
|
||||
expect(await login.signInPasswordHeader()).toEqual(true);
|
||||
});
|
||||
|
||||
test('verified, blocked', async ({ target, pages: { login, relier } }) => {
|
||||
const blockedEmail = login.createEmail('blocked{id}');
|
||||
await target.createAccount(blockedEmail, PASSWORD);
|
||||
|
||||
await relier.goto();
|
||||
await relier.clickEmailFirst();
|
||||
await login.login(blockedEmail, PASSWORD);
|
||||
|
||||
await login.unblock(blockedEmail);
|
||||
expect(await relier.isLoggedIn()).toBe(true);
|
||||
});
|
||||
|
||||
test('verified, blocked, incorrect password', async ({
|
||||
target,
|
||||
pages: { login, relier },
|
||||
}) => {
|
||||
const blockedEmail = login.createEmail('blocked{id}');
|
||||
await target.createAccount(blockedEmail, PASSWORD);
|
||||
|
||||
await relier.goto();
|
||||
await relier.clickEmailFirst();
|
||||
await login.login(blockedEmail, 'wrong password');
|
||||
|
||||
await login.unblock(blockedEmail);
|
||||
|
||||
// After filling in the unblock code, the user is prompted again to enter password
|
||||
expect(await login.signInPasswordHeader()).toEqual(true);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -1,112 +1,120 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
import { EmailHeader, EmailType } from '../../lib/email';
|
||||
import { test, expect } from '../../lib/fixtures/standard';
|
||||
|
||||
test.describe('OAuth signin token code', () => {
|
||||
function toQueryString(obj) {
|
||||
return Object.entries(obj)
|
||||
.map((x) => `${x[0]}=${x[1]}`)
|
||||
.join('&');
|
||||
}
|
||||
|
||||
/* Email for fake account */
|
||||
let email = '';
|
||||
|
||||
/* Password for fake account */
|
||||
const password = 'passwordzxcv';
|
||||
|
||||
/* eslint-disable camelcase */
|
||||
const queryParameters = {
|
||||
client_id: '7f368c6886429f19',
|
||||
code_challenge: 'aSOwsmuRBE1ZIVtiW6bzKMaf47kCFl7duD6ZWAXdnJo',
|
||||
code_challenge_method: 'S256',
|
||||
forceUA:
|
||||
'Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Mobile Safari/537.36',
|
||||
|
||||
keys_jwk:
|
||||
'eyJrdHkiOiJFQyIsImtpZCI6Im9DNGFudFBBSFZRX1pmQ09RRUYycTRaQlZYblVNZ2xISGpVRzdtSjZHOEEiLCJjcnYiOiJQLTI1NiIsIngiOiJDeUpUSjVwbUNZb2lQQnVWOTk1UjNvNTFLZVBMaEg1Y3JaQlkwbXNxTDk0IiwieSI6IkJCWDhfcFVZeHpTaldsdXU5MFdPTVZwamIzTlpVRDAyN0xwcC04RW9vckEifQ',
|
||||
redirect_uri: 'https://mozilla.github.io/notes/fxa/android-redirect.html',
|
||||
scope: 'profile https://identity.mozilla.com/apps/notes',
|
||||
};
|
||||
/* eslint-enable camelcase */
|
||||
|
||||
test.beforeEach(async ({ target }, { project }) => {
|
||||
// The `sync` prefix is needed to force confirmation.
|
||||
email = `sync${Math.random()}@restmail.net`;
|
||||
await target.createAccount(email, password);
|
||||
});
|
||||
|
||||
test.afterEach(async ({ target }) => {
|
||||
if (email) {
|
||||
// Cleanup any accounts created during the test
|
||||
try {
|
||||
await target.auth.accountDestroy(email, password);
|
||||
} catch (e) {}
|
||||
test.describe('severity-2 #smoke', () => {
|
||||
test.describe('OAuth signin token code', () => {
|
||||
function toQueryString(obj) {
|
||||
return Object.entries(obj)
|
||||
.map((x) => `${x[0]}=${x[1]}`)
|
||||
.join('&');
|
||||
}
|
||||
});
|
||||
|
||||
test('verified - invalid token', async ({
|
||||
page,
|
||||
pages: { login, relier, signinTokenCode },
|
||||
}) => {
|
||||
await relier.goto(toQueryString(queryParameters));
|
||||
/* Email for fake account */
|
||||
let email = '';
|
||||
|
||||
// Click the Email First flow, which should direct to the sign in page
|
||||
await relier.clickEmailFirst();
|
||||
/* Password for fake account */
|
||||
const password = 'passwordzxcv';
|
||||
|
||||
// Enter email, then enter password
|
||||
await login.fillOutEmailFirstSignIn(email, password);
|
||||
/* eslint-disable camelcase */
|
||||
const queryParameters = {
|
||||
client_id: '7f368c6886429f19',
|
||||
code_challenge: 'aSOwsmuRBE1ZIVtiW6bzKMaf47kCFl7duD6ZWAXdnJo',
|
||||
code_challenge_method: 'S256',
|
||||
forceUA:
|
||||
'Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Mobile Safari/537.36',
|
||||
|
||||
// Check that the sign in page is show, and is asking for a sign in code
|
||||
expect(await signinTokenCode.tokenCodeHeader.isVisible()).toBeTruthy();
|
||||
keys_jwk:
|
||||
'eyJrdHkiOiJFQyIsImtpZCI6Im9DNGFudFBBSFZRX1pmQ09RRUYycTRaQlZYblVNZ2xISGpVRzdtSjZHOEEiLCJjcnYiOiJQLTI1NiIsIngiOiJDeUpUSjVwbUNZb2lQQnVWOTk1UjNvNTFLZVBMaEg1Y3JaQlkwbXNxTDk0IiwieSI6IkJCWDhfcFVZeHpTaldsdXU5MFdPTVZwamIzTlpVRDAyN0xwcC04RW9vckEifQ',
|
||||
redirect_uri: 'https://mozilla.github.io/notes/fxa/android-redirect.html',
|
||||
scope: 'profile https://identity.mozilla.com/apps/notes',
|
||||
};
|
||||
/* eslint-enable camelcase */
|
||||
|
||||
// This will cause the token become 'invalid' and ultimately cause an
|
||||
// INVALID_TOKEN error to be thrown.
|
||||
await login.destroySession(email);
|
||||
await page.waitForURL(/oauth\/signin/);
|
||||
// Destroying the session should direct user back to sign in page
|
||||
await login.passwordHeader.waitFor({ state: 'visible' });
|
||||
});
|
||||
test.beforeEach(async ({ target }, { project }) => {
|
||||
// The `sync` prefix is needed to force confirmation.
|
||||
email = `sync${Math.random()}@restmail.net`;
|
||||
await target.createAccount(email, password);
|
||||
});
|
||||
|
||||
test('verified - valid code', async ({
|
||||
target,
|
||||
page,
|
||||
pages: { login, relier, signinTokenCode },
|
||||
}) => {
|
||||
await relier.goto(toQueryString(queryParameters));
|
||||
test.afterEach(async ({ target }) => {
|
||||
if (email) {
|
||||
// Cleanup any accounts created during the test
|
||||
try {
|
||||
await target.auth.accountDestroy(email, password);
|
||||
} catch (e) {}
|
||||
}
|
||||
});
|
||||
|
||||
// Click the Email First flow, which should direct to the sign in page
|
||||
await relier.clickEmailFirst();
|
||||
test('verified - invalid token', async ({
|
||||
page,
|
||||
pages: { login, relier, signinTokenCode },
|
||||
}) => {
|
||||
await relier.goto(toQueryString(queryParameters));
|
||||
|
||||
// Enter email, then enter password
|
||||
await login.fillOutEmailFirstSignIn(email, password);
|
||||
// Click the Email First flow, which should direct to the sign in page
|
||||
await relier.clickEmailFirst();
|
||||
|
||||
// Enter invalid code, ensure it doesn't work
|
||||
await signinTokenCode.input.fill('000000');
|
||||
await signinTokenCode.submit.click();
|
||||
await expect(signinTokenCode.tooltip).toContainText('Invalid or expired');
|
||||
// Enter email, then enter password
|
||||
await login.fillOutEmailFirstSignIn(email, password);
|
||||
|
||||
// Resend the code
|
||||
await signinTokenCode.resendLink.click();
|
||||
await signinTokenCode.successMessage.waitFor({ state: 'visible' });
|
||||
await expect(signinTokenCode.successMessage).toBeVisible();
|
||||
await expect(signinTokenCode.successMessage).toContainText('Email resent.');
|
||||
// Check that the sign in page is show, and is asking for a sign in code
|
||||
expect(await signinTokenCode.tokenCodeHeader.isVisible()).toBeTruthy();
|
||||
|
||||
// Correctly submits the token code and navigates to oauth page
|
||||
await expect(signinTokenCode.tokenCodeHeader).toBeVisible();
|
||||
// This will cause the token become 'invalid' and ultimately cause an
|
||||
// INVALID_TOKEN error to be thrown.
|
||||
await login.destroySession(email);
|
||||
await page.waitForURL(/oauth\/signin/);
|
||||
// Destroying the session should direct user back to sign in page
|
||||
await login.passwordHeader.waitFor({ state: 'visible' });
|
||||
});
|
||||
|
||||
const code = await target.email.waitForEmail(
|
||||
email,
|
||||
EmailType.verifyLoginCode,
|
||||
EmailHeader.signinCode
|
||||
);
|
||||
await signinTokenCode.input.fill(code);
|
||||
await signinTokenCode.submit.click();
|
||||
await page.waitForLoadState();
|
||||
test('verified - valid code', async ({
|
||||
target,
|
||||
page,
|
||||
pages: { login, relier, signinTokenCode },
|
||||
}) => {
|
||||
await relier.goto(toQueryString(queryParameters));
|
||||
|
||||
const NOTES_REDIRECT_PAGE_SELECTOR = '#notes-by-firefox';
|
||||
await expect(page.locator(NOTES_REDIRECT_PAGE_SELECTOR)).toBeVisible();
|
||||
await expect(page.locator(NOTES_REDIRECT_PAGE_SELECTOR)).toContainText(
|
||||
'Notes by Firefox'
|
||||
);
|
||||
// Click the Email First flow, which should direct to the sign in page
|
||||
await relier.clickEmailFirst();
|
||||
|
||||
// Enter email, then enter password
|
||||
await login.fillOutEmailFirstSignIn(email, password);
|
||||
|
||||
// Enter invalid code, ensure it doesn't work
|
||||
await signinTokenCode.input.fill('000000');
|
||||
await signinTokenCode.submit.click();
|
||||
await expect(signinTokenCode.tooltip).toContainText('Invalid or expired');
|
||||
|
||||
// Resend the code
|
||||
await signinTokenCode.resendLink.click();
|
||||
await signinTokenCode.successMessage.waitFor({ state: 'visible' });
|
||||
await expect(signinTokenCode.successMessage).toBeVisible();
|
||||
await expect(signinTokenCode.successMessage).toContainText(
|
||||
'Email resent.'
|
||||
);
|
||||
|
||||
// Correctly submits the token code and navigates to oauth page
|
||||
await expect(signinTokenCode.tokenCodeHeader).toBeVisible();
|
||||
|
||||
const code = await target.email.waitForEmail(
|
||||
email,
|
||||
EmailType.verifyLoginCode,
|
||||
EmailHeader.signinCode
|
||||
);
|
||||
await signinTokenCode.input.fill(code);
|
||||
await signinTokenCode.submit.click();
|
||||
await page.waitForLoadState();
|
||||
|
||||
const NOTES_REDIRECT_PAGE_SELECTOR = '#notes-by-firefox';
|
||||
await expect(page.locator(NOTES_REDIRECT_PAGE_SELECTOR)).toBeVisible();
|
||||
await expect(page.locator(NOTES_REDIRECT_PAGE_SELECTOR)).toContainText(
|
||||
'Notes by Firefox'
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -7,74 +7,76 @@ import { test, expect, newPagesForSync } from '../../lib/fixtures/standard';
|
|||
const password = 'passwordzxcv';
|
||||
let syncBrowserPages;
|
||||
|
||||
test.describe('signin with OAuth after Sync', () => {
|
||||
test.beforeEach(async ({ target }) => {
|
||||
test.slow();
|
||||
syncBrowserPages = await newPagesForSync(target);
|
||||
test.describe('severity-1 #smoke', () => {
|
||||
test.describe('signin with OAuth after Sync', () => {
|
||||
test.beforeEach(async ({ target }) => {
|
||||
test.slow();
|
||||
syncBrowserPages = await newPagesForSync(target);
|
||||
});
|
||||
|
||||
test.afterEach(async () => {
|
||||
await syncBrowserPages.browser?.close();
|
||||
});
|
||||
|
||||
test('signin to OAuth with Sync creds', async ({ target }) => {
|
||||
const { page, login, connectAnotherDevice, relier } = syncBrowserPages;
|
||||
|
||||
const email = login.createEmail('sync{id}');
|
||||
const email2 = login.createEmail();
|
||||
await target.createAccount(email, password);
|
||||
await page.goto(
|
||||
`${target.contentServerUrl}?context=fx_desktop_v3&service=sync&action=email&`
|
||||
);
|
||||
await login.login(email, password);
|
||||
await login.fillOutSignInCode(email);
|
||||
expect(await connectAnotherDevice.fxaConnected.isVisible()).toBeTruthy();
|
||||
await page.pause();
|
||||
|
||||
// Sign up for a new account via OAuth
|
||||
await relier.goto();
|
||||
await relier.clickEmailFirst();
|
||||
await login.useDifferentAccountLink();
|
||||
await login.fillOutFirstSignUp(email2, password);
|
||||
|
||||
// RP is logged in, logout then back in again
|
||||
expect(await relier.isLoggedIn()).toBe(true);
|
||||
await relier.signOut();
|
||||
|
||||
await relier.clickSignIn();
|
||||
|
||||
// By default, we should see the email we signed up for Sync with
|
||||
expect(await login.getPrefilledEmail()).toContain(email);
|
||||
await login.clickSignIn();
|
||||
expect(await relier.isLoggedIn()).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
test.afterEach(async () => {
|
||||
await syncBrowserPages.browser?.close();
|
||||
});
|
||||
test.describe('signin to Sync after OAuth', () => {
|
||||
test.beforeEach(async ({ target }) => {
|
||||
test.slow();
|
||||
syncBrowserPages = await newPagesForSync(target);
|
||||
});
|
||||
|
||||
test('signin to OAuth with Sync creds', async ({ target }) => {
|
||||
const { page, login, connectAnotherDevice, relier } = syncBrowserPages;
|
||||
test.afterEach(async () => {
|
||||
await syncBrowserPages.browser?.close();
|
||||
});
|
||||
|
||||
const email = login.createEmail('sync{id}');
|
||||
const email2 = login.createEmail();
|
||||
await target.createAccount(email, password);
|
||||
await page.goto(
|
||||
`${target.contentServerUrl}?context=fx_desktop_v3&service=sync&action=email&`
|
||||
);
|
||||
await login.login(email, password);
|
||||
await login.fillOutSignInCode(email);
|
||||
expect(await connectAnotherDevice.fxaConnected.isVisible()).toBeTruthy();
|
||||
await page.pause();
|
||||
test('email-first Sync signin', async ({ target }) => {
|
||||
const { page, login, connectAnotherDevice, relier } = syncBrowserPages;
|
||||
|
||||
// Sign up for a new account via OAuth
|
||||
await relier.goto();
|
||||
await relier.clickEmailFirst();
|
||||
await login.useDifferentAccountLink();
|
||||
await login.fillOutFirstSignUp(email2, password);
|
||||
|
||||
// RP is logged in, logout then back in again
|
||||
expect(await relier.isLoggedIn()).toBe(true);
|
||||
await relier.signOut();
|
||||
|
||||
await relier.clickSignIn();
|
||||
|
||||
// By default, we should see the email we signed up for Sync with
|
||||
expect(await login.getPrefilledEmail()).toContain(email);
|
||||
await login.clickSignIn();
|
||||
expect(await relier.isLoggedIn()).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
test.describe('signin to Sync after OAuth', () => {
|
||||
test.beforeEach(async ({ target }) => {
|
||||
test.slow();
|
||||
syncBrowserPages = await newPagesForSync(target);
|
||||
});
|
||||
|
||||
test.afterEach(async () => {
|
||||
await syncBrowserPages.browser?.close();
|
||||
});
|
||||
|
||||
test('email-first Sync signin', async ({ target }) => {
|
||||
const { page, login, connectAnotherDevice, relier } = syncBrowserPages;
|
||||
|
||||
const email = login.createEmail('sync{id}');
|
||||
await relier.goto();
|
||||
await relier.clickEmailFirst();
|
||||
await login.fillOutFirstSignUp(email, password);
|
||||
expect(await relier.isLoggedIn()).toBe(true);
|
||||
await page.goto(
|
||||
`${target.contentServerUrl}?context=fx_desktop_v3&service=sync&action=email&`
|
||||
);
|
||||
expect(await login.getPrefilledEmail()).toContain(email);
|
||||
await login.setPassword(password);
|
||||
await login.submit();
|
||||
await login.fillOutSignInCode(email);
|
||||
expect(await connectAnotherDevice.fxaConnected.isVisible()).toBeTruthy();
|
||||
const email = login.createEmail('sync{id}');
|
||||
await relier.goto();
|
||||
await relier.clickEmailFirst();
|
||||
await login.fillOutFirstSignUp(email, password);
|
||||
expect(await relier.isLoggedIn()).toBe(true);
|
||||
await page.goto(
|
||||
`${target.contentServerUrl}?context=fx_desktop_v3&service=sync&action=email&`
|
||||
);
|
||||
expect(await login.getPrefilledEmail()).toContain(email);
|
||||
await login.setPassword(password);
|
||||
await login.submit();
|
||||
await login.fillOutSignInCode(email);
|
||||
expect(await connectAnotherDevice.fxaConnected.isVisible()).toBeTruthy();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -1,45 +1,51 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
import { test, expect } from '../../lib/fixtures/standard';
|
||||
|
||||
test.describe('OAuth totp', () => {
|
||||
test.beforeEach(async ({}, { project }) => {
|
||||
test.slow();
|
||||
});
|
||||
test.describe('severity-1 #smoke', () => {
|
||||
test.describe('OAuth totp', () => {
|
||||
test.beforeEach(async ({}, { project }) => {
|
||||
test.slow();
|
||||
});
|
||||
|
||||
test('can add TOTP to account and confirm oauth signin', async ({
|
||||
credentials,
|
||||
pages: { login, relier, settings, totp },
|
||||
}) => {
|
||||
await settings.goto();
|
||||
await settings.totp.clickAdd();
|
||||
await totp.enable(credentials);
|
||||
await settings.signOut();
|
||||
test('can add TOTP to account and confirm oauth signin', async ({
|
||||
credentials,
|
||||
pages: { login, relier, settings, totp },
|
||||
}) => {
|
||||
await settings.goto();
|
||||
await settings.totp.clickAdd();
|
||||
await totp.enable(credentials);
|
||||
await settings.signOut();
|
||||
|
||||
await relier.goto();
|
||||
await relier.clickEmailFirst();
|
||||
await login.login(credentials.email, credentials.password);
|
||||
await login.setTotp(credentials.secret);
|
||||
await relier.goto();
|
||||
await relier.clickEmailFirst();
|
||||
await login.login(credentials.email, credentials.password);
|
||||
await login.setTotp(credentials.secret);
|
||||
|
||||
expect(await relier.isLoggedIn()).toBe(true);
|
||||
});
|
||||
expect(await relier.isLoggedIn()).toBe(true);
|
||||
});
|
||||
|
||||
test('can remove TOTP from account and skip confirmation', async ({
|
||||
credentials,
|
||||
pages: { login, relier, settings, totp },
|
||||
}) => {
|
||||
await settings.goto();
|
||||
await settings.totp.clickAdd();
|
||||
await totp.enable(credentials);
|
||||
test('can remove TOTP from account and skip confirmation', async ({
|
||||
credentials,
|
||||
pages: { login, relier, settings, totp },
|
||||
}) => {
|
||||
await settings.goto();
|
||||
await settings.totp.clickAdd();
|
||||
await totp.enable(credentials);
|
||||
|
||||
await settings.totp.clickDisable();
|
||||
await settings.clickModalConfirm();
|
||||
await settings.waitForAlertBar();
|
||||
let status = await settings.totp.statusText();
|
||||
expect(status).toEqual('Not Set');
|
||||
await settings.totp.clickDisable();
|
||||
await settings.clickModalConfirm();
|
||||
await settings.waitForAlertBar();
|
||||
let status = await settings.totp.statusText();
|
||||
expect(status).toEqual('Not Set');
|
||||
|
||||
await relier.goto();
|
||||
await relier.clickEmailFirst();
|
||||
await login.login(credentials.email, credentials.password);
|
||||
await relier.goto();
|
||||
await relier.clickEmailFirst();
|
||||
await login.login(credentials.email, credentials.password);
|
||||
|
||||
expect(await relier.isLoggedIn()).toBe(true);
|
||||
expect(await relier.isLoggedIn()).toBe(true);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -7,66 +7,68 @@ import { test, expect } from '../../lib/fixtures/standard';
|
|||
|
||||
const PASSWORD = 'Password123!';
|
||||
|
||||
test.describe('oauth webchannel', () => {
|
||||
test.beforeEach(async ({ pages: { login } }) => {
|
||||
await login.clearCache();
|
||||
});
|
||||
|
||||
test('signup', async ({ pages: { login, relier } }) => {
|
||||
const customEventDetail = createCustomEventDetail(
|
||||
FirefoxCommand.FxAStatus,
|
||||
{
|
||||
capabilities: {
|
||||
choose_what_to_sync: true,
|
||||
engines: ['bookmarks', 'history'],
|
||||
},
|
||||
signedInUser: null,
|
||||
}
|
||||
);
|
||||
const email = login.createEmail();
|
||||
|
||||
await relier.goto('context=oauth_webchannel_v1&automatedBrowser=true');
|
||||
await relier.clickEmailFirst();
|
||||
|
||||
await login.respondToWebChannelMessage(customEventDetail);
|
||||
|
||||
await login.setEmail(email);
|
||||
await login.submit();
|
||||
|
||||
// the CWTS form is on the same signup page
|
||||
await login.waitForCWTSEngineHeader();
|
||||
expect(await login.isCWTSEngineBookmarks()).toBe(true);
|
||||
expect(await login.isCWTSEngineHistory()).toBe(true);
|
||||
|
||||
await login.fillOutFirstSignUp(email, PASSWORD, {
|
||||
enterEmail: false,
|
||||
waitForNavOnSubmit: false,
|
||||
test.describe('severity-1 #smoke', () => {
|
||||
test.describe('oauth webchannel', () => {
|
||||
test.beforeEach(async ({ pages: { login } }) => {
|
||||
await login.clearCache();
|
||||
});
|
||||
await login.checkWebChannelMessage(FirefoxCommand.OAuthLogin);
|
||||
});
|
||||
|
||||
test('signin', async ({ pages: { login, relier, page }, credentials }) => {
|
||||
const customEventDetail = createCustomEventDetail(
|
||||
FirefoxCommand.FxAStatus,
|
||||
{
|
||||
capabilities: {
|
||||
engines: ['bookmarks', 'history'],
|
||||
},
|
||||
signedInUser: null,
|
||||
}
|
||||
);
|
||||
test('signup', async ({ pages: { login, relier } }) => {
|
||||
const customEventDetail = createCustomEventDetail(
|
||||
FirefoxCommand.FxAStatus,
|
||||
{
|
||||
capabilities: {
|
||||
choose_what_to_sync: true,
|
||||
engines: ['bookmarks', 'history'],
|
||||
},
|
||||
signedInUser: null,
|
||||
}
|
||||
);
|
||||
const email = login.createEmail();
|
||||
|
||||
await relier.goto('context=oauth_webchannel_v1&automatedBrowser=true');
|
||||
await relier.clickEmailFirst();
|
||||
await relier.goto('context=oauth_webchannel_v1&automatedBrowser=true');
|
||||
await relier.clickEmailFirst();
|
||||
|
||||
await login.respondToWebChannelMessage(customEventDetail);
|
||||
await login.respondToWebChannelMessage(customEventDetail);
|
||||
|
||||
const { searchParams } = new URL(page.url());
|
||||
expect(searchParams.has('client_id')).toBe(true);
|
||||
expect(searchParams.has('redirect_uri')).toBe(true);
|
||||
expect(searchParams.has('state')).toBe(true);
|
||||
expect(searchParams.has('context')).toBe(true);
|
||||
await login.setEmail(email);
|
||||
await login.submit();
|
||||
|
||||
await login.login(credentials.email, credentials.password, '', false);
|
||||
// the CWTS form is on the same signup page
|
||||
await login.waitForCWTSEngineHeader();
|
||||
expect(await login.isCWTSEngineBookmarks()).toBe(true);
|
||||
expect(await login.isCWTSEngineHistory()).toBe(true);
|
||||
|
||||
await login.fillOutFirstSignUp(email, PASSWORD, {
|
||||
enterEmail: false,
|
||||
waitForNavOnSubmit: false,
|
||||
});
|
||||
await login.checkWebChannelMessage(FirefoxCommand.OAuthLogin);
|
||||
});
|
||||
|
||||
test('signin', async ({ pages: { login, relier, page }, credentials }) => {
|
||||
const customEventDetail = createCustomEventDetail(
|
||||
FirefoxCommand.FxAStatus,
|
||||
{
|
||||
capabilities: {
|
||||
engines: ['bookmarks', 'history'],
|
||||
},
|
||||
signedInUser: null,
|
||||
}
|
||||
);
|
||||
|
||||
await relier.goto('context=oauth_webchannel_v1&automatedBrowser=true');
|
||||
await relier.clickEmailFirst();
|
||||
|
||||
await login.respondToWebChannelMessage(customEventDetail);
|
||||
|
||||
const { searchParams } = new URL(page.url());
|
||||
expect(searchParams.has('client_id')).toBe(true);
|
||||
expect(searchParams.has('redirect_uri')).toBe(true);
|
||||
expect(searchParams.has('state')).toBe(true);
|
||||
expect(searchParams.has('context')).toBe(true);
|
||||
|
||||
await login.login(credentials.email, credentials.password, '', false);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -6,127 +6,129 @@ import { test, expect } from '../../lib/fixtures/standard';
|
|||
const password = 'passwordzxcv';
|
||||
let email;
|
||||
|
||||
test.describe('post verify - account recovery', () => {
|
||||
test.beforeEach(async ({ target, pages: { login } }) => {
|
||||
// Generating and consuming recovery keys is a slow process
|
||||
test.slow();
|
||||
email = login.createEmail();
|
||||
await target.auth.signUp(email, password, {
|
||||
lang: 'en',
|
||||
preVerified: 'true',
|
||||
test.describe('severity-1 #smoke', () => {
|
||||
test.describe('post verify - account recovery', () => {
|
||||
test.beforeEach(async ({ target, pages: { login } }) => {
|
||||
// Generating and consuming recovery keys is a slow process
|
||||
test.slow();
|
||||
email = login.createEmail();
|
||||
await target.auth.signUp(email, password, {
|
||||
lang: 'en',
|
||||
preVerified: 'true',
|
||||
});
|
||||
await login.clearCache();
|
||||
});
|
||||
await login.clearCache();
|
||||
});
|
||||
|
||||
test.afterEach(async ({ target }) => {
|
||||
if (email) {
|
||||
// Cleanup any accounts created during the test
|
||||
try {
|
||||
await target.auth.accountDestroy(email, password);
|
||||
} catch (e) {
|
||||
// Handle the error here
|
||||
console.error('An error occurred during account cleanup:', e);
|
||||
// Optionally, rethrow the error to propagate it further
|
||||
throw e;
|
||||
test.afterEach(async ({ target }) => {
|
||||
if (email) {
|
||||
// Cleanup any accounts created during the test
|
||||
try {
|
||||
await target.auth.accountDestroy(email, password);
|
||||
} catch (e) {
|
||||
// Handle the error here
|
||||
console.error('An error occurred during account cleanup:', e);
|
||||
// Optionally, rethrow the error to propagate it further
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
test('create account recovery', async ({
|
||||
target,
|
||||
pages: { page, login, postVerify },
|
||||
}) => {
|
||||
await page.goto(target.contentServerUrl, {
|
||||
waitUntil: 'load',
|
||||
});
|
||||
await login.fillOutEmailFirstSignIn(email, password);
|
||||
|
||||
//Verify logged in on Settings page
|
||||
expect(await login.isUserLoggedIn()).toBe(true);
|
||||
test('create account recovery', async ({
|
||||
target,
|
||||
pages: { page, login, postVerify },
|
||||
}) => {
|
||||
await page.goto(target.contentServerUrl, {
|
||||
waitUntil: 'load',
|
||||
});
|
||||
await login.fillOutEmailFirstSignIn(email, password);
|
||||
|
||||
await page.goto(
|
||||
`${target.contentServerUrl}/post_verify/account_recovery/add_recovery_key`,
|
||||
{ waitUntil: 'load' }
|
||||
);
|
||||
//Verify logged in on Settings page
|
||||
expect(await login.isUserLoggedIn()).toBe(true);
|
||||
|
||||
//Verify account recovery header
|
||||
expect(await postVerify.isAccountRecoveryHeader()).toBe(true);
|
||||
await page.goto(
|
||||
`${target.contentServerUrl}/post_verify/account_recovery/add_recovery_key`,
|
||||
{ waitUntil: 'load' }
|
||||
);
|
||||
|
||||
//Add recovery key
|
||||
await postVerify.addRecoveryKey(password);
|
||||
await postVerify.submit();
|
||||
//Verify account recovery header
|
||||
expect(await postVerify.isAccountRecoveryHeader()).toBe(true);
|
||||
|
||||
// Store key to be used later
|
||||
const key = await postVerify.getKey();
|
||||
await postVerify.clickDone();
|
||||
//Add recovery key
|
||||
await postVerify.addRecoveryKey(password);
|
||||
await postVerify.submit();
|
||||
|
||||
//Enter invalid key
|
||||
await postVerify.inputRecoveryKey('invalid key');
|
||||
// Store key to be used later
|
||||
const key = await postVerify.getKey();
|
||||
await postVerify.clickDone();
|
||||
|
||||
//Verify error message
|
||||
expect(await postVerify.getTooltipError()).toContain(
|
||||
'Invalid account recovery key'
|
||||
);
|
||||
//Enter invalid key
|
||||
await postVerify.inputRecoveryKey('invalid key');
|
||||
|
||||
//Enter correct key
|
||||
await postVerify.inputRecoveryKey(key);
|
||||
//Verify error message
|
||||
expect(await postVerify.getTooltipError()).toContain(
|
||||
'Invalid account recovery key'
|
||||
);
|
||||
|
||||
//Verify post verify account recovery key complete header
|
||||
expect(await postVerify.isAccountRecoveryVerifiedHeader()).toBe(true);
|
||||
});
|
||||
//Enter correct key
|
||||
await postVerify.inputRecoveryKey(key);
|
||||
|
||||
test('abort account recovery at add_recovery_key', async ({
|
||||
target,
|
||||
pages: { page, login, postVerify },
|
||||
}) => {
|
||||
await page.goto(target.contentServerUrl, {
|
||||
waitUntil: 'load',
|
||||
//Verify post verify account recovery key complete header
|
||||
expect(await postVerify.isAccountRecoveryVerifiedHeader()).toBe(true);
|
||||
});
|
||||
await login.fillOutEmailFirstSignIn(email, password);
|
||||
|
||||
//Verify logged in on Settings page
|
||||
expect(await login.isUserLoggedIn()).toBe(true);
|
||||
test('abort account recovery at add_recovery_key', async ({
|
||||
target,
|
||||
pages: { page, login, postVerify },
|
||||
}) => {
|
||||
await page.goto(target.contentServerUrl, {
|
||||
waitUntil: 'load',
|
||||
});
|
||||
await login.fillOutEmailFirstSignIn(email, password);
|
||||
|
||||
await page.goto(
|
||||
`${target.contentServerUrl}/post_verify/account_recovery/add_recovery_key`,
|
||||
{ waitUntil: 'load' }
|
||||
);
|
||||
//Verify logged in on Settings page
|
||||
expect(await login.isUserLoggedIn()).toBe(true);
|
||||
|
||||
//Verify account recovery header
|
||||
expect(await postVerify.isAccountRecoveryHeader()).toBe(true);
|
||||
await page.goto(
|
||||
`${target.contentServerUrl}/post_verify/account_recovery/add_recovery_key`,
|
||||
{ waitUntil: 'load' }
|
||||
);
|
||||
|
||||
//Add recovery key
|
||||
await postVerify.clickMaybeLater();
|
||||
//Verify account recovery header
|
||||
expect(await postVerify.isAccountRecoveryHeader()).toBe(true);
|
||||
|
||||
//Verify logged in on Settings page
|
||||
expect(await login.isUserLoggedIn()).toBe(true);
|
||||
});
|
||||
//Add recovery key
|
||||
await postVerify.clickMaybeLater();
|
||||
|
||||
test('abort account recovery at confirm_recovery_key', async ({
|
||||
target,
|
||||
pages: { page, login, postVerify },
|
||||
}) => {
|
||||
await page.goto(target.contentServerUrl, {
|
||||
waitUntil: 'load',
|
||||
//Verify logged in on Settings page
|
||||
expect(await login.isUserLoggedIn()).toBe(true);
|
||||
});
|
||||
await login.fillOutEmailFirstSignIn(email, password);
|
||||
|
||||
//Verify logged in on Settings page
|
||||
expect(await login.isUserLoggedIn()).toBe(true);
|
||||
test('abort account recovery at confirm_recovery_key', async ({
|
||||
target,
|
||||
pages: { page, login, postVerify },
|
||||
}) => {
|
||||
await page.goto(target.contentServerUrl, {
|
||||
waitUntil: 'load',
|
||||
});
|
||||
await login.fillOutEmailFirstSignIn(email, password);
|
||||
|
||||
await page.goto(
|
||||
`${target.contentServerUrl}/post_verify/account_recovery/add_recovery_key`,
|
||||
{ waitUntil: 'load' }
|
||||
);
|
||||
//Verify logged in on Settings page
|
||||
expect(await login.isUserLoggedIn()).toBe(true);
|
||||
|
||||
//Verify account recovery header
|
||||
expect(await postVerify.isAccountRecoveryHeader()).toBe(true);
|
||||
await page.goto(
|
||||
`${target.contentServerUrl}/post_verify/account_recovery/add_recovery_key`,
|
||||
{ waitUntil: 'load' }
|
||||
);
|
||||
|
||||
//Add recovery key
|
||||
await postVerify.addRecoveryKey(password);
|
||||
await postVerify.clickMaybeLater();
|
||||
//Verify account recovery header
|
||||
expect(await postVerify.isAccountRecoveryHeader()).toBe(true);
|
||||
|
||||
//Verify logged in on Settings page
|
||||
expect(await login.isUserLoggedIn()).toBe(true);
|
||||
//Add recovery key
|
||||
await postVerify.addRecoveryKey(password);
|
||||
await postVerify.clickMaybeLater();
|
||||
|
||||
//Verify logged in on Settings page
|
||||
expect(await login.isUserLoggedIn()).toBe(true);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -7,68 +7,70 @@ let email;
|
|||
const password = 'password';
|
||||
const newPassword = 'new_password';
|
||||
|
||||
test.describe('post verify - force password change', () => {
|
||||
test.beforeEach(async ({ target, pages: { login } }) => {
|
||||
test.slow();
|
||||
email = login.createEmail('forcepwdchange{id}');
|
||||
await target.auth.signUp(email, password, {
|
||||
lang: 'en',
|
||||
preVerified: 'true',
|
||||
test.describe('severity-2 #smoke', () => {
|
||||
test.describe('post verify - force password change', () => {
|
||||
test.beforeEach(async ({ target, pages: { login } }) => {
|
||||
test.slow();
|
||||
email = login.createEmail('forcepwdchange{id}');
|
||||
await target.auth.signUp(email, password, {
|
||||
lang: 'en',
|
||||
preVerified: 'true',
|
||||
});
|
||||
await login.clearCache();
|
||||
});
|
||||
await login.clearCache();
|
||||
});
|
||||
|
||||
test.afterEach(async ({ target }) => {
|
||||
if (email) {
|
||||
// Cleanup any accounts created during the test
|
||||
try {
|
||||
await target.auth.accountDestroy(email, newPassword);
|
||||
} catch (e) {
|
||||
// Handle the error here
|
||||
console.error('An error occurred during account cleanup:', e);
|
||||
// Optionally, rethrow the error to propagate it further
|
||||
throw e;
|
||||
test.afterEach(async ({ target }) => {
|
||||
if (email) {
|
||||
// Cleanup any accounts created during the test
|
||||
try {
|
||||
await target.auth.accountDestroy(email, newPassword);
|
||||
} catch (e) {
|
||||
// Handle the error here
|
||||
console.error('An error occurred during account cleanup:', e);
|
||||
// Optionally, rethrow the error to propagate it further
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
test('navigate to page directly and can change password', async ({
|
||||
target,
|
||||
pages: { page, login, postVerify },
|
||||
}) => {
|
||||
await page.goto(target.contentServerUrl, {
|
||||
waitUntil: 'load',
|
||||
});
|
||||
await login.fillOutEmailFirstSignIn(email, password);
|
||||
await login.fillOutSignInCode(email);
|
||||
|
||||
//Verify force password change header
|
||||
expect(await postVerify.isForcePasswordChangeHeader()).toBe(true);
|
||||
test('navigate to page directly and can change password', async ({
|
||||
target,
|
||||
pages: { page, login, postVerify },
|
||||
}) => {
|
||||
await page.goto(target.contentServerUrl, {
|
||||
waitUntil: 'load',
|
||||
});
|
||||
await login.fillOutEmailFirstSignIn(email, password);
|
||||
await login.fillOutSignInCode(email);
|
||||
|
||||
//Fill out change password
|
||||
await postVerify.fillOutChangePassword(password, newPassword);
|
||||
await postVerify.submit();
|
||||
//Verify force password change header
|
||||
expect(await postVerify.isForcePasswordChangeHeader()).toBe(true);
|
||||
|
||||
//Verify logged in on Settings page
|
||||
expect(await login.isUserLoggedIn()).toBe(true);
|
||||
});
|
||||
//Fill out change password
|
||||
await postVerify.fillOutChangePassword(password, newPassword);
|
||||
await postVerify.submit();
|
||||
|
||||
test('force change password on login - oauth', async ({
|
||||
pages: { login, postVerify, relier },
|
||||
}) => {
|
||||
await relier.goto();
|
||||
await relier.clickEmailFirst();
|
||||
await login.fillOutEmailFirstSignIn(email, password);
|
||||
await login.fillOutSignInCode(email);
|
||||
//Verify logged in on Settings page
|
||||
expect(await login.isUserLoggedIn()).toBe(true);
|
||||
});
|
||||
|
||||
//Verify force password change header
|
||||
expect(await postVerify.isForcePasswordChangeHeader()).toBe(true);
|
||||
test('force change password on login - oauth', async ({
|
||||
pages: { login, postVerify, relier },
|
||||
}) => {
|
||||
await relier.goto();
|
||||
await relier.clickEmailFirst();
|
||||
await login.fillOutEmailFirstSignIn(email, password);
|
||||
await login.fillOutSignInCode(email);
|
||||
|
||||
//Fill out change password
|
||||
await postVerify.fillOutChangePassword(password, newPassword);
|
||||
await postVerify.submit();
|
||||
//Verify force password change header
|
||||
expect(await postVerify.isForcePasswordChangeHeader()).toBe(true);
|
||||
|
||||
//Verify logged in on relier page
|
||||
expect(await relier.isLoggedIn()).toBe(true);
|
||||
//Fill out change password
|
||||
await postVerify.fillOutChangePassword(password, newPassword);
|
||||
await postVerify.submit();
|
||||
|
||||
//Verify logged in on relier page
|
||||
expect(await relier.isLoggedIn()).toBe(true);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -8,51 +8,54 @@ const password = 'password';
|
|||
const newPassword = 'new_password';
|
||||
let syncBrowserPages;
|
||||
|
||||
test.describe('post verify - force password change sync', () => {
|
||||
test.beforeEach(async ({ target }) => {
|
||||
syncBrowserPages = await newPagesForSync(target);
|
||||
const { login } = syncBrowserPages;
|
||||
email = login.createEmail('forcepwdchange{id}');
|
||||
await target.auth.signUp(email, password, {
|
||||
lang: 'en',
|
||||
preVerified: 'true',
|
||||
test.describe('severity-2 #smoke', () => {
|
||||
test.describe('post verify - force password change sync', () => {
|
||||
test.beforeEach(async ({ target }) => {
|
||||
syncBrowserPages = await newPagesForSync(target);
|
||||
const { login } = syncBrowserPages;
|
||||
email = login.createEmail('forcepwdchange{id}');
|
||||
await target.auth.signUp(email, password, {
|
||||
lang: 'en',
|
||||
preVerified: 'true',
|
||||
});
|
||||
});
|
||||
|
||||
test.afterEach(async ({ target }) => {
|
||||
await syncBrowserPages.browser?.close();
|
||||
if (email) {
|
||||
// Cleanup any accounts created during the test
|
||||
try {
|
||||
await target.auth.accountDestroy(email, newPassword);
|
||||
} catch (e) {
|
||||
// Handle the error here
|
||||
console.error('An error occurred during account cleanup:', e);
|
||||
// Optionally, rethrow the error to propagate it further
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
test('force change password on login - sync', async ({ target }) => {
|
||||
const { page, login, postVerify, connectAnotherDevice } =
|
||||
syncBrowserPages;
|
||||
await page.goto(
|
||||
`${target.contentServerUrl}?context=fx_desktop_v3&service=sync`,
|
||||
{
|
||||
waitUntil: 'load',
|
||||
}
|
||||
);
|
||||
await login.fillOutEmailFirstSignIn(email, password);
|
||||
await login.fillOutSignInCode(email);
|
||||
|
||||
//Verify force password change header
|
||||
expect(await postVerify.isForcePasswordChangeHeader()).toBe(true);
|
||||
|
||||
//Fill out change password
|
||||
await postVerify.fillOutChangePassword(password, newPassword);
|
||||
await postVerify.submit();
|
||||
|
||||
//Verify logged in on connect another device page
|
||||
expect(await connectAnotherDevice.fxaConnected.isEnabled()).toBeTruthy();
|
||||
});
|
||||
});
|
||||
|
||||
test.afterEach(async ({ target }) => {
|
||||
await syncBrowserPages.browser?.close();
|
||||
if (email) {
|
||||
// Cleanup any accounts created during the test
|
||||
try {
|
||||
await target.auth.accountDestroy(email, newPassword);
|
||||
} catch (e) {
|
||||
// Handle the error here
|
||||
console.error('An error occurred during account cleanup:', e);
|
||||
// Optionally, rethrow the error to propagate it further
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
test('force change password on login - sync', async ({ target }) => {
|
||||
const { page, login, postVerify, connectAnotherDevice } = syncBrowserPages;
|
||||
await page.goto(
|
||||
`${target.contentServerUrl}?context=fx_desktop_v3&service=sync`,
|
||||
{
|
||||
waitUntil: 'load',
|
||||
}
|
||||
);
|
||||
await login.fillOutEmailFirstSignIn(email, password);
|
||||
await login.fillOutSignInCode(email);
|
||||
|
||||
//Verify force password change header
|
||||
expect(await postVerify.isForcePasswordChangeHeader()).toBe(true);
|
||||
|
||||
//Fill out change password
|
||||
await postVerify.fillOutChangePassword(password, newPassword);
|
||||
await postVerify.submit();
|
||||
|
||||
//Verify logged in on connect another device page
|
||||
expect(await connectAnotherDevice.fxaConnected.isEnabled()).toBeTruthy();
|
||||
});
|
||||
});
|
||||
|
|
|
@ -11,60 +11,62 @@ test.beforeEach(async ({ pages: { configPage } }) => {
|
|||
test.skip(config.showReactApp.simpleRoutes !== true);
|
||||
});
|
||||
|
||||
test.describe('legal', () => {
|
||||
test('start at legal page', async ({ page, target }) => {
|
||||
await page.goto(getReactFeatureFlagUrl(target, '/legal'));
|
||||
test.describe('severity-2 #smoke', () => {
|
||||
test.describe('legal', () => {
|
||||
test('start at legal page', async ({ page, target }) => {
|
||||
await page.goto(getReactFeatureFlagUrl(target, '/legal'));
|
||||
|
||||
// Verify react page has been loaded
|
||||
expect(await page.locator('#root').isEnabled()).toBeTruthy();
|
||||
// Verify react page has been loaded
|
||||
expect(await page.locator('#root').isEnabled()).toBeTruthy();
|
||||
|
||||
// Verify legal page is visible
|
||||
expect(
|
||||
await page.locator('.card-header:has-text("Legal")').isEnabled()
|
||||
).toBeTruthy();
|
||||
// Verify legal page is visible
|
||||
expect(
|
||||
await page.locator('.card-header:has-text("Legal")').isEnabled()
|
||||
).toBeTruthy();
|
||||
|
||||
// Verify Terms Of Service link is visible
|
||||
expect(
|
||||
await page.locator('a:has-text("Terms of Service")').isVisible()
|
||||
).toBeTruthy();
|
||||
// Verify Terms Of Service link is visible
|
||||
expect(
|
||||
await page.locator('a:has-text("Terms of Service")').isVisible()
|
||||
).toBeTruthy();
|
||||
|
||||
// Currently Back button on this page is not working,
|
||||
// check https://mozilla-hub.atlassian.net/browse/FXA-6874
|
||||
// await page.locator('a:has-text("Terms of Service")').click();
|
||||
//await page.locator('button:has-text("Back")').click();
|
||||
//expect(await page.locator('.card-header:has-text("Legal")').isVisible()).toBeTruthy();
|
||||
// Currently Back button on this page is not working,
|
||||
// check https://mozilla-hub.atlassian.net/browse/FXA-6874
|
||||
// await page.locator('a:has-text("Terms of Service")').click();
|
||||
//await page.locator('button:has-text("Back")').click();
|
||||
//expect(await page.locator('.card-header:has-text("Legal")').isVisible()).toBeTruthy();
|
||||
|
||||
// Verify Privacy Notice link is visible
|
||||
expect(
|
||||
await page.locator('a:has-text("Privacy Notice")').isVisible()
|
||||
).toBeTruthy();
|
||||
await page.locator('a:has-text("Privacy Notice")').click();
|
||||
await page.locator('button:has-text("Back")').click();
|
||||
await page.waitForSelector('.card-header:has-text("Legal")');
|
||||
});
|
||||
// Verify Privacy Notice link is visible
|
||||
expect(
|
||||
await page.locator('a:has-text("Privacy Notice")').isVisible()
|
||||
).toBeTruthy();
|
||||
await page.locator('a:has-text("Privacy Notice")').click();
|
||||
await page.locator('button:has-text("Back")').click();
|
||||
await page.waitForSelector('.card-header:has-text("Legal")');
|
||||
});
|
||||
|
||||
test('start at terms page', async ({ page, target }) => {
|
||||
await page.goto(getReactFeatureFlagUrl(target, '/legal/terms'));
|
||||
test('start at terms page', async ({ page, target }) => {
|
||||
await page.goto(getReactFeatureFlagUrl(target, '/legal/terms'));
|
||||
|
||||
// Verify react page has been loaded
|
||||
await page.locator('#root').isVisible();
|
||||
// Verify react page has been loaded
|
||||
await page.locator('#root').isVisible();
|
||||
|
||||
// Verify legal page is visible
|
||||
// this text is not in our codebase, it's pulled from the `legal-docs` repo
|
||||
await page
|
||||
.locator('text="Firefox Cloud Services: Terms of Service"')
|
||||
.isVisible();
|
||||
});
|
||||
// Verify legal page is visible
|
||||
// this text is not in our codebase, it's pulled from the `legal-docs` repo
|
||||
await page
|
||||
.locator('text="Firefox Cloud Services: Terms of Service"')
|
||||
.isVisible();
|
||||
});
|
||||
|
||||
test('start at privacy page', async ({ page, target }) => {
|
||||
await page.goto(getReactFeatureFlagUrl(target, '/legal/privacy'));
|
||||
test('start at privacy page', async ({ page, target }) => {
|
||||
await page.goto(getReactFeatureFlagUrl(target, '/legal/privacy'));
|
||||
|
||||
// Verify react page has been loaded
|
||||
await page.locator('#root').isVisible();
|
||||
// Verify react page has been loaded
|
||||
await page.locator('#root').isVisible();
|
||||
|
||||
// Verify privacy page is visible
|
||||
await page.waitForTimeout(1000);
|
||||
// this text is not in our codebase, it's pulled from the `legal-docs` repo
|
||||
await page.locator('text="Firefox Privacy Notice"').isVisible();
|
||||
// Verify privacy page is visible
|
||||
await page.waitForTimeout(1000);
|
||||
// this text is not in our codebase, it's pulled from the `legal-docs` repo
|
||||
await page.locator('text="Firefox Privacy Notice"').isVisible();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -5,294 +5,299 @@
|
|||
import { test, expect } from '../../lib/fixtures/standard';
|
||||
import { EmailHeader, EmailType } from '../../lib/email';
|
||||
|
||||
test.describe('oauth reset password react', () => {
|
||||
let resetPasswordReactFlag = false;
|
||||
test.describe('severity-1 #smoke', () => {
|
||||
test.describe('oauth reset password react', () => {
|
||||
let resetPasswordReactFlag = false;
|
||||
|
||||
test.beforeEach(async ({ pages: { configPage, resetPassword } }) => {
|
||||
resetPasswordReactFlag = resetPassword.react;
|
||||
resetPassword.react = true;
|
||||
test.slow();
|
||||
test.beforeEach(async ({ pages: { configPage, resetPassword } }) => {
|
||||
resetPasswordReactFlag = resetPassword.react;
|
||||
resetPassword.react = true;
|
||||
test.slow();
|
||||
|
||||
const config = await configPage.getConfig();
|
||||
test.skip(config.showReactApp.resetPasswordRoutes !== true);
|
||||
});
|
||||
|
||||
test.afterEach(async ({ pages: { resetPassword } }) => {
|
||||
resetPassword.react = resetPasswordReactFlag;
|
||||
});
|
||||
|
||||
test('reset password', async ({
|
||||
target,
|
||||
page,
|
||||
credentials,
|
||||
pages: { login, relier, resetPassword, settings },
|
||||
}) => {
|
||||
await openRelier({ pages: { settings, relier } });
|
||||
await passwordResetFlow(
|
||||
{
|
||||
target,
|
||||
page,
|
||||
credentials,
|
||||
pages: { login, relier, resetPassword },
|
||||
},
|
||||
{}
|
||||
);
|
||||
});
|
||||
|
||||
test('reset password different tab', async ({
|
||||
target,
|
||||
page,
|
||||
credentials,
|
||||
pages: { login, relier, resetPassword, settings },
|
||||
}) => {
|
||||
await openRelier({ pages: { relier, settings } });
|
||||
await passwordResetFlow(
|
||||
{
|
||||
target,
|
||||
page,
|
||||
credentials,
|
||||
pages: { login, relier, resetPassword },
|
||||
},
|
||||
{
|
||||
newTab: true,
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
test('reset password scoped keys', async ({
|
||||
target,
|
||||
page,
|
||||
credentials,
|
||||
pages: { login, relier, resetPassword, settings },
|
||||
}) => {
|
||||
await openRelier({ pages: { relier, settings } });
|
||||
await passwordResetFlow(
|
||||
{
|
||||
target,
|
||||
page,
|
||||
credentials,
|
||||
pages: { login, relier, resetPassword },
|
||||
},
|
||||
{
|
||||
action: 'scopedKeys',
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
test('reset password with PKCE different tab', async ({
|
||||
target,
|
||||
page,
|
||||
credentials,
|
||||
pages: { login, relier, resetPassword },
|
||||
}) => {
|
||||
await passwordResetFlow(
|
||||
{
|
||||
target,
|
||||
page,
|
||||
credentials,
|
||||
pages: { login, relier, resetPassword },
|
||||
},
|
||||
{
|
||||
action: 'pkce',
|
||||
newTab: true,
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
test('reset password with account recovery key', async ({
|
||||
target,
|
||||
credentials,
|
||||
page,
|
||||
pages: { login, resetPassword, relier, settings, recoveryKey },
|
||||
}) => {
|
||||
const accountRecoveryKey = await addAccountRecoveryKeyFlow({
|
||||
credentials,
|
||||
pages: { settings, recoveryKey },
|
||||
const config = await configPage.getConfig();
|
||||
test.skip(config.showReactApp.resetPasswordRoutes !== true);
|
||||
});
|
||||
await openRelier({ pages: { relier, settings } });
|
||||
await passwordResetFlow(
|
||||
{
|
||||
target,
|
||||
|
||||
test.afterEach(async ({ pages: { resetPassword } }) => {
|
||||
resetPassword.react = resetPasswordReactFlag;
|
||||
});
|
||||
|
||||
test('reset password', async ({
|
||||
target,
|
||||
page,
|
||||
credentials,
|
||||
pages: { login, relier, resetPassword, settings },
|
||||
}) => {
|
||||
await openRelier({ pages: { settings, relier } });
|
||||
await passwordResetFlow(
|
||||
{
|
||||
target,
|
||||
page,
|
||||
credentials,
|
||||
pages: { login, relier, resetPassword },
|
||||
},
|
||||
{}
|
||||
);
|
||||
});
|
||||
|
||||
test('reset password different tab', async ({
|
||||
target,
|
||||
page,
|
||||
credentials,
|
||||
pages: { login, relier, resetPassword, settings },
|
||||
}) => {
|
||||
await openRelier({ pages: { relier, settings } });
|
||||
await passwordResetFlow(
|
||||
{
|
||||
target,
|
||||
page,
|
||||
credentials,
|
||||
pages: { login, relier, resetPassword },
|
||||
},
|
||||
{
|
||||
newTab: true,
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
test('reset password scoped keys', async ({
|
||||
target,
|
||||
page,
|
||||
credentials,
|
||||
pages: { login, relier, resetPassword, settings },
|
||||
}) => {
|
||||
await openRelier({ pages: { relier, settings } });
|
||||
await passwordResetFlow(
|
||||
{
|
||||
target,
|
||||
page,
|
||||
credentials,
|
||||
pages: { login, relier, resetPassword },
|
||||
},
|
||||
{
|
||||
action: 'scopedKeys',
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
/* Disabling this until FXA-8006 is fixed
|
||||
test('reset password with PKCE different tab', async ({
|
||||
target,
|
||||
page,
|
||||
credentials,
|
||||
pages: { login, relier, resetPassword },
|
||||
}) => {
|
||||
await passwordResetFlow(
|
||||
{
|
||||
target,
|
||||
page,
|
||||
credentials,
|
||||
pages: { login, relier, resetPassword },
|
||||
},
|
||||
{
|
||||
action: 'pkce',
|
||||
newTab: true,
|
||||
}
|
||||
);
|
||||
});*/
|
||||
|
||||
test('reset password with account recovery key', async ({
|
||||
target,
|
||||
credentials,
|
||||
page,
|
||||
pages: { login, resetPassword, relier, settings, recoveryKey },
|
||||
}) => {
|
||||
const accountRecoveryKey = await addAccountRecoveryKeyFlow({
|
||||
credentials,
|
||||
page,
|
||||
pages: { login, resetPassword, relier },
|
||||
},
|
||||
{
|
||||
action: 'emailFirst',
|
||||
accountRecoveryKey,
|
||||
}
|
||||
);
|
||||
pages: { settings, recoveryKey },
|
||||
});
|
||||
await openRelier({ pages: { relier, settings } });
|
||||
await passwordResetFlow(
|
||||
{
|
||||
target,
|
||||
credentials,
|
||||
page,
|
||||
pages: { login, resetPassword, relier },
|
||||
},
|
||||
{
|
||||
action: 'emailFirst',
|
||||
accountRecoveryKey,
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
test('reset password with valid totp', async ({
|
||||
target,
|
||||
credentials,
|
||||
page,
|
||||
pages: { login, resetPassword, relier, totp, settings },
|
||||
}) => {
|
||||
await addTotpFlow({ credentials, pages: { totp, settings } });
|
||||
await openRelier({ pages: { relier, settings } });
|
||||
await passwordResetFlow(
|
||||
{
|
||||
target,
|
||||
credentials,
|
||||
page,
|
||||
pages: { login, resetPassword, relier },
|
||||
},
|
||||
{
|
||||
action: 'emailFirst',
|
||||
}
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
test('reset password with valid totp', async ({
|
||||
target,
|
||||
/**
|
||||
* Makes sure user is not signed in, and goes to the relier (ie 123done)
|
||||
*/
|
||||
async function openRelier({ pages: { settings, relier } }) {
|
||||
await relier.goto('showReactApp=true');
|
||||
}
|
||||
|
||||
/**
|
||||
* Goes to settings and enables totp on user's account.
|
||||
*/
|
||||
async function addTotpFlow({ credentials, pages: { totp, settings } }) {
|
||||
await settings.goto();
|
||||
await settings.totp.clickAdd();
|
||||
await totp.enable(credentials);
|
||||
}
|
||||
|
||||
/**
|
||||
* Goes to settings and enables the account recovery key on user's account.
|
||||
*/
|
||||
async function addAccountRecoveryKeyFlow({
|
||||
credentials,
|
||||
page,
|
||||
pages: { login, resetPassword, relier, totp, settings },
|
||||
}) => {
|
||||
await addTotpFlow({ credentials, pages: { totp, settings } });
|
||||
await openRelier({ pages: { relier, settings } });
|
||||
await passwordResetFlow(
|
||||
{
|
||||
target,
|
||||
credentials,
|
||||
page,
|
||||
pages: { login, resetPassword, relier },
|
||||
},
|
||||
{
|
||||
action: 'emailFirst',
|
||||
}
|
||||
);
|
||||
});
|
||||
});
|
||||
pages: { settings, recoveryKey },
|
||||
}) {
|
||||
await settings.goto();
|
||||
await settings.recoveryKey.clickCreate();
|
||||
await recoveryKey.clickStart();
|
||||
await recoveryKey.setPassword(credentials.password);
|
||||
await recoveryKey.clickCreateAccountRecoveryKey();
|
||||
const accountRecoveryKey = await recoveryKey.getKey();
|
||||
await recoveryKey.clickNext();
|
||||
await recoveryKey.clickFinish();
|
||||
|
||||
/**
|
||||
* Makes sure user is not signed in, and goes to the relier (ie 123done)
|
||||
*/
|
||||
async function openRelier({ pages: { settings, relier } }) {
|
||||
await relier.goto('showReactApp=true');
|
||||
}
|
||||
|
||||
/**
|
||||
* Goes to settings and enables totp on user's account.
|
||||
*/
|
||||
async function addTotpFlow({ credentials, pages: { totp, settings } }) {
|
||||
await settings.goto();
|
||||
await settings.totp.clickAdd();
|
||||
await totp.enable(credentials);
|
||||
}
|
||||
|
||||
/**
|
||||
* Goes to settings and enables the account recovery key on user's account.
|
||||
*/
|
||||
async function addAccountRecoveryKeyFlow({
|
||||
credentials,
|
||||
pages: { settings, recoveryKey },
|
||||
}) {
|
||||
await settings.goto();
|
||||
await settings.recoveryKey.clickCreate();
|
||||
await recoveryKey.clickStart();
|
||||
await recoveryKey.setPassword(credentials.password);
|
||||
await recoveryKey.clickCreateAccountRecoveryKey();
|
||||
const accountRecoveryKey = await recoveryKey.getKey();
|
||||
await recoveryKey.clickNext();
|
||||
await recoveryKey.clickFinish();
|
||||
|
||||
return accountRecoveryKey;
|
||||
}
|
||||
|
||||
/**
|
||||
* Primary function for running various permutations on reset password flows
|
||||
* @param param0
|
||||
* @param opts {
|
||||
* action - The button to click on the relier 123done
|
||||
* newTab - Whether or not the flow is conducted in a single tab, or if the processes is carried out
|
||||
* in one tab, and then another after the confirmation email is received.
|
||||
* accountRecoveryKey - If account recovery keys were enabled, then supply the key and activate that
|
||||
* part of the flow.
|
||||
* totp - If 2 factor auth is enabled, then activate that part of the flow.
|
||||
* }
|
||||
*/
|
||||
async function passwordResetFlow(
|
||||
{ target, page, credentials, pages: { login, relier, resetPassword } },
|
||||
opts: {
|
||||
action?: 'emailFirst' | 'scopedKeys' | 'pkce';
|
||||
newTab?: boolean;
|
||||
accountRecoveryKey?: string;
|
||||
}
|
||||
) {
|
||||
const { action, newTab, accountRecoveryKey } = opts;
|
||||
|
||||
// Decide which flow to start from 123done
|
||||
if (action == null || action === 'emailFirst') {
|
||||
await relier.clickEmailFirst();
|
||||
} else if (action === 'scopedKeys') {
|
||||
await relier.clickSignInScopedKeys();
|
||||
} else if (action === 'pkce') {
|
||||
// TODO, the PKCE button is broken at the moment, so for now navigate directly to the link.
|
||||
// TODO: PKCE button doesn't appear to work at the moment locally. Some sort of cors error keeps getting in the way. Just go to link directly for now.
|
||||
await page.goto(
|
||||
'http://localhost:3030/authorization?showReactApp=true&access_type=offline&client_id=dcdb5ae7add825d2&pkce_client_id=38a6b9b3a65a1871&redirect_uri=http%3A%2F%2Flocalhost%3A8080%2Fapi%2Foauth&scope=profile%20openid&action=signin&state=12eeaba43cc7548bf1f6b478b9de95328855b46df1e754fe94b21036c41c9cba',
|
||||
{
|
||||
waitUntil: 'load',
|
||||
}
|
||||
);
|
||||
return accountRecoveryKey;
|
||||
}
|
||||
|
||||
// Step 1 - Begin the password reset.
|
||||
// - Go to the login page
|
||||
// - Enter current email
|
||||
// - Select the forgot password link
|
||||
/**
|
||||
* Primary function for running various permutations on reset password flows
|
||||
* @param param0
|
||||
* @param opts {
|
||||
* action - The button to click on the relier 123done
|
||||
* newTab - Whether or not the flow is conducted in a single tab, or if the processes is carried out
|
||||
* in one tab, and then another after the confirmation email is received.
|
||||
* accountRecoveryKey - If account recovery keys were enabled, then supply the key and activate that
|
||||
* part of the flow.
|
||||
* totp - If 2 factor auth is enabled, then activate that part of the flow.
|
||||
* }
|
||||
*/
|
||||
async function passwordResetFlow(
|
||||
{ target, page, credentials, pages: { login, relier, resetPassword } },
|
||||
opts: {
|
||||
action?: 'emailFirst' | 'scopedKeys' | 'pkce';
|
||||
newTab?: boolean;
|
||||
accountRecoveryKey?: string;
|
||||
}
|
||||
) {
|
||||
const { action, newTab, accountRecoveryKey } = opts;
|
||||
|
||||
// TODO: Update once we port signin / signup.
|
||||
// param is set, this view is still using backbone.
|
||||
await login.setEmail(credentials.email);
|
||||
await login.submit();
|
||||
await login.clickForgotPassword();
|
||||
// Decide which flow to start from 123done
|
||||
if (action == null || action === 'emailFirst') {
|
||||
await relier.clickEmailFirst();
|
||||
} else if (action === 'scopedKeys') {
|
||||
await relier.clickSignInScopedKeys();
|
||||
} else if (action === 'pkce') {
|
||||
// TODO, the PKCE button is broken at the moment, so for now navigate directly to the link.
|
||||
// TODO: PKCE button doesn't appear to work at the moment locally. Some sort of cors error keeps getting in the way. Just go to link directly for now.
|
||||
await page.goto(
|
||||
'http://localhost:3030/authorization?showReactApp=true&access_type=offline&client_id=dcdb5ae7add825d2&pkce_client_id=38a6b9b3a65a1871&redirect_uri=http%3A%2F%2Flocalhost%3A8080%2Fapi%2Foauth&scope=profile%20openid&action=signin&state=12eeaba43cc7548bf1f6b478b9de95328855b46df1e754fe94b21036c41c9cba',
|
||||
{
|
||||
waitUntil: 'load',
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
// TODO: Once the full flow is implemented in react, we can remove this. For now, we must 'refresh'
|
||||
// the page so that the 'showReactApp' param takes effect. Once conversion is complete this can be removed
|
||||
await page.reload();
|
||||
await checkForReactApp({ page });
|
||||
// Step 1 - Begin the password reset.
|
||||
// - Go to the login page
|
||||
// - Enter current email
|
||||
// - Select the forgot password link
|
||||
|
||||
// Verify reset password header
|
||||
// The service name can change based on environments and all of our test RPs have service names
|
||||
// that begin with '123'. This test just ensures that the OAuth service name is rendered, it's
|
||||
// OK that it does not exactly match.
|
||||
expect(
|
||||
await resetPassword.resetPasswordHeader('Reset password to continue to 123')
|
||||
).toBe(true);
|
||||
|
||||
await resetPassword.fillOutResetPassword(credentials.email);
|
||||
|
||||
// Step 2 - Get the confirmation email
|
||||
let link = await target.email.waitForEmail(
|
||||
credentials.email,
|
||||
EmailType.recovery,
|
||||
EmailHeader.link
|
||||
);
|
||||
// Make sure showReactApp is appended to link
|
||||
link = link.includes('showReactApp=true')
|
||||
? link
|
||||
: link.includes('?')
|
||||
? `${link}&showReactApp=true`
|
||||
: `${link}?showReactApp=true`;
|
||||
|
||||
// Clearing session state simulates a 'new' tab, and changes the navigation at the end of the flow.
|
||||
if (newTab) {
|
||||
await page.evaluate(() => window.sessionStorage.clear());
|
||||
}
|
||||
|
||||
// Step 3 (optional) - Reset the password!
|
||||
await page.goto(link, { waitUntil: 'load' });
|
||||
await checkForReactApp({ page });
|
||||
|
||||
// This is an alternate flow for accounts with recovery keys
|
||||
if (accountRecoveryKey) {
|
||||
await login.setRecoveryKey(accountRecoveryKey);
|
||||
// TODO: Update once we port signin / signup.
|
||||
// param is set, this view is still using backbone.
|
||||
await login.setEmail(credentials.email);
|
||||
await login.submit();
|
||||
await login.clickForgotPassword();
|
||||
|
||||
// TODO: Once the full flow is implemented in react, we can remove this. For now, we must 'refresh'
|
||||
// the page so that the 'showReactApp' param takes effect. Once conversion is complete this can be removed
|
||||
await page.reload();
|
||||
await checkForReactApp({ page });
|
||||
|
||||
// Verify reset password header
|
||||
// The service name can change based on environments and all of our test RPs have service names
|
||||
// that begin with '123'. This test just ensures that the OAuth service name is rendered, it's
|
||||
// OK that it does not exactly match.
|
||||
expect(
|
||||
await resetPassword.resetPasswordHeader(
|
||||
'Reset password to continue to 123'
|
||||
)
|
||||
).toBe(true);
|
||||
|
||||
await resetPassword.fillOutResetPassword(credentials.email);
|
||||
|
||||
// Step 2 - Get the confirmation email
|
||||
let link = await target.email.waitForEmail(
|
||||
credentials.email,
|
||||
EmailType.recovery,
|
||||
EmailHeader.link
|
||||
);
|
||||
// Make sure showReactApp is appended to link
|
||||
link = link.includes('showReactApp=true')
|
||||
? link
|
||||
: link.includes('?')
|
||||
? `${link}&showReactApp=true`
|
||||
: `${link}?showReactApp=true`;
|
||||
|
||||
// Clearing session state simulates a 'new' tab, and changes the navigation at the end of the flow.
|
||||
if (newTab) {
|
||||
await page.evaluate(() => window.sessionStorage.clear());
|
||||
}
|
||||
|
||||
// Step 3 (optional) - Reset the password!
|
||||
await page.goto(link, { waitUntil: 'load' });
|
||||
await checkForReactApp({ page });
|
||||
|
||||
// This is an alternate flow for accounts with recovery keys
|
||||
if (accountRecoveryKey) {
|
||||
await login.setRecoveryKey(accountRecoveryKey);
|
||||
await login.submit();
|
||||
}
|
||||
await resetPassword.resetNewPassword(credentials.password);
|
||||
|
||||
// Step 4 - Verify the end state. The user should either be:
|
||||
// See a nice success message in fxa. Note, that we used to redirect the user back to
|
||||
// the relier in some cases, but we've decided to just show the success message for now
|
||||
// And let the user re-authenticate with the relier.
|
||||
await isSuccessMessageDisplayed({ page });
|
||||
}
|
||||
await resetPassword.resetNewPassword(credentials.password);
|
||||
|
||||
// Step 4 - Verify the end state. The user should either be:
|
||||
// See a nice success message in fxa. Note, that we used to redirect the user back to
|
||||
// the relier in some cases, but we've decided to just show the success message for now
|
||||
// And let the user re-authenticate with the relier.
|
||||
await isSuccessMessageDisplayed({ page });
|
||||
}
|
||||
/** Checks that the reset password success screen is being displayed. */
|
||||
async function isSuccessMessageDisplayed({ page }) {
|
||||
// The user should get a verification message and the originating
|
||||
// service's name should be displayed.
|
||||
await page.waitForURL(
|
||||
/(reset_password_verified|reset_password_with_recovery_key_verified)/
|
||||
);
|
||||
await page.getByText('Your password has been reset').waitFor();
|
||||
await page.getByText(/.*123done.*/i).waitFor();
|
||||
}
|
||||
|
||||
/** Checks that the reset password success screen is being displayed. */
|
||||
async function isSuccessMessageDisplayed({ page }) {
|
||||
// The user should get a verification message and the originating
|
||||
// service's name should be displayed.
|
||||
await page.waitForURL(
|
||||
/(reset_password_verified|reset_password_with_recovery_key_verified)/
|
||||
);
|
||||
await page.getByText('Your password has been reset').waitFor();
|
||||
await page.getByText(/.*123done.*/i).waitFor();
|
||||
}
|
||||
|
||||
/** Checks that the version of the app being used is the React Version. */
|
||||
async function checkForReactApp({ page }) {
|
||||
expect(await page.locator('#root')).toBeVisible();
|
||||
}
|
||||
/** Checks that the version of the app being used is the React Version. */
|
||||
async function checkForReactApp({ page }) {
|
||||
expect(await page.locator('#root')).toBeVisible();
|
||||
}
|
||||
});
|
||||
|
|
|
@ -7,140 +7,142 @@ let originalEncryptionKeys;
|
|||
|
||||
const NEW_PASSWORD = 'notYourAveragePassW0Rd';
|
||||
|
||||
test.describe('recovery key react', () => {
|
||||
test.beforeEach(
|
||||
async ({
|
||||
target,
|
||||
credentials,
|
||||
pages: { login, configPage, settings, recoveryKey },
|
||||
}) => {
|
||||
// Generating and consuming recovery keys is a slow process
|
||||
test.slow();
|
||||
test.describe('severity-1 #smoke', () => {
|
||||
test.describe('recovery key react', () => {
|
||||
test.beforeEach(
|
||||
async ({
|
||||
target,
|
||||
credentials,
|
||||
pages: { login, configPage, settings, recoveryKey },
|
||||
}) => {
|
||||
// Generating and consuming recovery keys is a slow process
|
||||
test.slow();
|
||||
|
||||
// Ensure that the react reset password route feature flag is enabled
|
||||
const config = await configPage.getConfig();
|
||||
test.skip(config.showReactApp.resetPasswordRoutes !== true);
|
||||
// Ensure that the react reset password route feature flag is enabled
|
||||
const config = await configPage.getConfig();
|
||||
test.skip(config.showReactApp.resetPasswordRoutes !== true);
|
||||
|
||||
await settings.goto();
|
||||
let status = await settings.recoveryKey.statusText();
|
||||
expect(status).toEqual('Not Set');
|
||||
|
||||
// Check which account recovery key generation flow to use (based on feature flag)
|
||||
// TODO in FXA-7419 - remove the condition and else block that goes through the old key generation flow
|
||||
if (config.featureFlags.showRecoveryKeyV2 === true) {
|
||||
await settings.goto();
|
||||
await settings.recoveryKey.clickCreate();
|
||||
// View 1/4 info
|
||||
await recoveryKey.clickStart();
|
||||
// View 2/4 confirm password and generate key
|
||||
await recoveryKey.setPassword(credentials.password);
|
||||
await recoveryKey.submit();
|
||||
let status = await settings.recoveryKey.statusText();
|
||||
expect(status).toEqual('Not Set');
|
||||
|
||||
// View 3/4 key download
|
||||
// Store key to be used later
|
||||
key = await recoveryKey.getKey();
|
||||
await recoveryKey.clickNext();
|
||||
// Check which account recovery key generation flow to use (based on feature flag)
|
||||
// TODO in FXA-7419 - remove the condition and else block that goes through the old key generation flow
|
||||
if (config.featureFlags.showRecoveryKeyV2 === true) {
|
||||
await settings.goto();
|
||||
await settings.recoveryKey.clickCreate();
|
||||
// View 1/4 info
|
||||
await recoveryKey.clickStart();
|
||||
// View 2/4 confirm password and generate key
|
||||
await recoveryKey.setPassword(credentials.password);
|
||||
await recoveryKey.submit();
|
||||
|
||||
// View 4/4 hint
|
||||
// store hint to be used later
|
||||
hint = 'secret key location';
|
||||
await recoveryKey.setHint(hint);
|
||||
await recoveryKey.clickFinish();
|
||||
} else {
|
||||
await settings.recoveryKey.clickCreate();
|
||||
await recoveryKey.setPassword(credentials.password);
|
||||
await recoveryKey.submit();
|
||||
// View 3/4 key download
|
||||
// Store key to be used later
|
||||
key = await recoveryKey.getKey();
|
||||
await recoveryKey.clickNext();
|
||||
|
||||
// Store key to be used later
|
||||
key = await recoveryKey.getKey();
|
||||
await recoveryKey.clickClose();
|
||||
// View 4/4 hint
|
||||
// store hint to be used later
|
||||
hint = 'secret key location';
|
||||
await recoveryKey.setHint(hint);
|
||||
await recoveryKey.clickFinish();
|
||||
} else {
|
||||
await settings.recoveryKey.clickCreate();
|
||||
await recoveryKey.setPassword(credentials.password);
|
||||
await recoveryKey.submit();
|
||||
|
||||
// Store key to be used later
|
||||
key = await recoveryKey.getKey();
|
||||
await recoveryKey.clickClose();
|
||||
}
|
||||
|
||||
// Verify status as 'enabled'
|
||||
status = await settings.recoveryKey.statusText();
|
||||
expect(status).toEqual('Enabled');
|
||||
|
||||
// Ensure password reset occurs with no session token available
|
||||
login.clearCache();
|
||||
// Stash original encryption keys to be verified later
|
||||
const res = await target.auth.sessionReauth(
|
||||
credentials.sessionToken,
|
||||
credentials.email,
|
||||
credentials.password,
|
||||
{
|
||||
keys: true,
|
||||
reason: 'recovery_key',
|
||||
}
|
||||
);
|
||||
originalEncryptionKeys = await target.auth.accountKeys(
|
||||
res.keyFetchToken,
|
||||
res.unwrapBKey
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
// Verify status as 'enabled'
|
||||
status = await settings.recoveryKey.statusText();
|
||||
expect(status).toEqual('Enabled');
|
||||
test('can reset password with recovery key', async ({
|
||||
credentials,
|
||||
target,
|
||||
page,
|
||||
pages: { resetPasswordReact },
|
||||
}) => {
|
||||
await resetPasswordReact.goto();
|
||||
|
||||
// Ensure password reset occurs with no session token available
|
||||
login.clearCache();
|
||||
// Stash original encryption keys to be verified later
|
||||
const res = await target.auth.sessionReauth(
|
||||
credentials.sessionToken,
|
||||
// Verify react page is loaded
|
||||
await page.waitForSelector('#root');
|
||||
|
||||
await resetPasswordReact.fillEmailToResetPwd(credentials.email);
|
||||
await resetPasswordReact.confirmResetPasswordHeadingVisible();
|
||||
|
||||
// We need to append `&showReactApp=true` to reset link in order to enroll in reset password experiment
|
||||
let link = await target.email.waitForEmail(
|
||||
credentials.email,
|
||||
credentials.password,
|
||||
EmailType.recovery,
|
||||
EmailHeader.link
|
||||
);
|
||||
link = `${link}&showReactApp=true`;
|
||||
|
||||
// Loads the React version
|
||||
await page.goto(link);
|
||||
// Verify react page is loaded
|
||||
await page.waitForSelector('#root');
|
||||
|
||||
await resetPasswordReact.confirmRecoveryKeyHeadingVisible();
|
||||
|
||||
await resetPasswordReact.submitRecoveryKey(key);
|
||||
await page.waitForURL(/account_recovery_reset_password/);
|
||||
|
||||
await resetPasswordReact.submitNewPassword(NEW_PASSWORD);
|
||||
await page.waitForURL(/reset_password_with_recovery_key_verified/);
|
||||
|
||||
// Attempt to login with new password
|
||||
const { sessionToken } = await target.auth.signIn(
|
||||
credentials.email,
|
||||
NEW_PASSWORD
|
||||
);
|
||||
|
||||
const res = await target.auth.sessionReauth(
|
||||
sessionToken,
|
||||
credentials.email,
|
||||
NEW_PASSWORD,
|
||||
{
|
||||
keys: true,
|
||||
reason: 'recovery_key',
|
||||
}
|
||||
);
|
||||
originalEncryptionKeys = await target.auth.accountKeys(
|
||||
const newEncryptionKeys = await target.auth.accountKeys(
|
||||
res.keyFetchToken,
|
||||
res.unwrapBKey
|
||||
);
|
||||
}
|
||||
);
|
||||
expect(originalEncryptionKeys).toEqual(newEncryptionKeys);
|
||||
|
||||
test('can reset password with recovery key', async ({
|
||||
credentials,
|
||||
target,
|
||||
page,
|
||||
pages: { resetPasswordReact },
|
||||
}) => {
|
||||
await resetPasswordReact.goto();
|
||||
// Cleanup requires setting this value to correct password
|
||||
credentials.password = NEW_PASSWORD;
|
||||
|
||||
// Verify react page is loaded
|
||||
await page.waitForSelector('#root');
|
||||
|
||||
await resetPasswordReact.fillEmailToResetPwd(credentials.email);
|
||||
await resetPasswordReact.confirmResetPasswordHeadingVisible();
|
||||
|
||||
// We need to append `&showReactApp=true` to reset link in order to enroll in reset password experiment
|
||||
let link = await target.email.waitForEmail(
|
||||
credentials.email,
|
||||
EmailType.recovery,
|
||||
EmailHeader.link
|
||||
);
|
||||
link = `${link}&showReactApp=true`;
|
||||
|
||||
// Loads the React version
|
||||
await page.goto(link);
|
||||
// Verify react page is loaded
|
||||
await page.waitForSelector('#root');
|
||||
|
||||
await resetPasswordReact.confirmRecoveryKeyHeadingVisible();
|
||||
|
||||
await resetPasswordReact.submitRecoveryKey(key);
|
||||
await page.waitForURL(/account_recovery_reset_password/);
|
||||
|
||||
await resetPasswordReact.submitNewPassword(NEW_PASSWORD);
|
||||
await page.waitForURL(/reset_password_with_recovery_key_verified/);
|
||||
|
||||
// Attempt to login with new password
|
||||
const { sessionToken } = await target.auth.signIn(
|
||||
credentials.email,
|
||||
NEW_PASSWORD
|
||||
);
|
||||
|
||||
const res = await target.auth.sessionReauth(
|
||||
sessionToken,
|
||||
credentials.email,
|
||||
NEW_PASSWORD,
|
||||
{
|
||||
keys: true,
|
||||
reason: 'recovery_key',
|
||||
}
|
||||
);
|
||||
const newEncryptionKeys = await target.auth.accountKeys(
|
||||
res.keyFetchToken,
|
||||
res.unwrapBKey
|
||||
);
|
||||
expect(originalEncryptionKeys).toEqual(newEncryptionKeys);
|
||||
|
||||
// Cleanup requires setting this value to correct password
|
||||
credentials.password = NEW_PASSWORD;
|
||||
|
||||
await page
|
||||
.getByRole('button', { name: 'Generate a new account recovery key' })
|
||||
.click();
|
||||
await page.waitForURL(/settings\/account_recovery/);
|
||||
await page
|
||||
.getByRole('button', { name: 'Generate a new account recovery key' })
|
||||
.click();
|
||||
await page.waitForURL(/settings\/account_recovery/);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -8,236 +8,238 @@ import { getReactFeatureFlagUrl } from '../../lib/react-flag';
|
|||
|
||||
const NEW_PASSWORD = 'notYourAveragePassW0Rd';
|
||||
|
||||
test.describe('reset password react', () => {
|
||||
test.beforeEach(async ({ pages: { configPage } }) => {
|
||||
test.slow();
|
||||
// Ensure that the feature flag is enabled
|
||||
const config = await configPage.getConfig();
|
||||
test.skip(config.showReactApp.resetPasswordRoutes !== true);
|
||||
});
|
||||
|
||||
test('can reset password', async ({
|
||||
page,
|
||||
target,
|
||||
credentials,
|
||||
context,
|
||||
pages: { login, resetPasswordReact },
|
||||
}) => {
|
||||
await resetPasswordReact.goto();
|
||||
|
||||
// Verify react page has been loaded
|
||||
await page.waitForSelector('#root');
|
||||
|
||||
await resetPasswordReact.fillEmailToResetPwd(credentials.email);
|
||||
|
||||
// Wait for navigation after email submitted
|
||||
await page.waitForURL(
|
||||
getReactFeatureFlagUrl(target, '/confirm_reset_password')
|
||||
);
|
||||
|
||||
// Verify confirm password reset page rendered
|
||||
await resetPasswordReact.confirmResetPasswordHeadingVisible();
|
||||
|
||||
// We need to append `&showReactApp=true` to reset link in order to enroll in reset password experiment
|
||||
let link = await target.email.waitForEmail(
|
||||
credentials.email,
|
||||
EmailType.recovery,
|
||||
EmailHeader.link
|
||||
);
|
||||
link = `${link}&showReactApp=true`;
|
||||
|
||||
// Open link in a new window
|
||||
const diffPage = await context.newPage();
|
||||
await diffPage.goto(link);
|
||||
|
||||
// Renders the React version of complete password reset page
|
||||
await page.waitForSelector('#root');
|
||||
|
||||
await resetPasswordReact.completeResetPwdHeadingVisible(diffPage);
|
||||
|
||||
// Create and submit new password
|
||||
await resetPasswordReact.submitNewPassword(NEW_PASSWORD, diffPage);
|
||||
|
||||
// Wait for new page to navigate
|
||||
await diffPage.waitForURL(/reset_password_verified/);
|
||||
|
||||
// Wait for initial page to automatically redirect once password is reset
|
||||
await page.waitForURL(`${target.contentServerUrl}/signin`);
|
||||
|
||||
// Verify password reset confirmation page is rendered
|
||||
await resetPasswordReact.resetPwdConfirmedHeadingVisible(diffPage);
|
||||
|
||||
await diffPage.close();
|
||||
|
||||
// Verify initial page redirected to sign in and sign in page rendered
|
||||
await login.emailHeader.waitFor();
|
||||
|
||||
await login.setEmail(credentials.email);
|
||||
await login.clickSubmit();
|
||||
await page.waitForURL(`${target.contentServerUrl}/signin`);
|
||||
|
||||
await login.setPassword(NEW_PASSWORD);
|
||||
await login.clickSubmit();
|
||||
await page.waitForURL(`${target.contentServerUrl}/settings`);
|
||||
|
||||
await page.getByRole('heading', { name: 'Settings', level: 2 }).waitFor();
|
||||
|
||||
// Check that connected service name is not empty!
|
||||
expect(await page.getByTestId('service-name').innerText()).toContain(
|
||||
'Firefox'
|
||||
);
|
||||
|
||||
// Cleanup requires setting this value to correct password
|
||||
credentials.password = NEW_PASSWORD;
|
||||
});
|
||||
|
||||
test('cannot set an invalid password', async ({
|
||||
page,
|
||||
target,
|
||||
credentials,
|
||||
context,
|
||||
pages: { login, resetPasswordReact },
|
||||
}) => {
|
||||
await resetPasswordReact.goto();
|
||||
|
||||
// Verify react page has been loaded
|
||||
await page.waitForSelector('#root');
|
||||
|
||||
await resetPasswordReact.fillEmailToResetPwd(credentials.email);
|
||||
|
||||
// Wait for navigation after email submitted
|
||||
await page.waitForURL(
|
||||
getReactFeatureFlagUrl(target, '/confirm_reset_password')
|
||||
);
|
||||
|
||||
// Verify confirm password reset page rendered
|
||||
await resetPasswordReact.confirmResetPasswordHeadingVisible();
|
||||
|
||||
// We need to append `&showReactApp=true` to reset link in order to enroll in reset password experiment
|
||||
let link = await target.email.waitForEmail(
|
||||
credentials.email,
|
||||
EmailType.recovery,
|
||||
EmailHeader.link
|
||||
);
|
||||
link = `${link}&showReactApp=true`;
|
||||
|
||||
// Open link in a new window
|
||||
const diffPage = await context.newPage();
|
||||
await diffPage.goto(link);
|
||||
|
||||
// Renders the React version of complete password reset page
|
||||
await page.waitForSelector('#root');
|
||||
await resetPasswordReact.completeResetPwdHeadingVisible(diffPage);
|
||||
|
||||
// Attempt to submit short password
|
||||
await resetPasswordReact.submitNewPassword('2short', diffPage);
|
||||
|
||||
await diffPage.getByText('At least 8 characters').waitFor();
|
||||
await expect(
|
||||
diffPage.getByRole('textbox', { name: 'New password' })
|
||||
).toBeFocused();
|
||||
|
||||
// Attempt to submit email as password
|
||||
await resetPasswordReact.submitNewPassword(credentials.email, diffPage);
|
||||
|
||||
await diffPage.getByText('Not your email').waitFor();
|
||||
await expect(
|
||||
diffPage.getByRole('textbox', { name: 'New password' })
|
||||
).toBeFocused();
|
||||
|
||||
// Attempt to submit a common password
|
||||
await resetPasswordReact.submitNewPassword('password', diffPage);
|
||||
|
||||
await diffPage.getByText('Not a commonly used password').waitFor();
|
||||
await expect(
|
||||
diffPage.getByRole('textbox', { name: 'New password' })
|
||||
).toBeFocused();
|
||||
});
|
||||
|
||||
test('visit confirmation screen without initiating reset_password, user is redirected to /reset_password', async ({
|
||||
target,
|
||||
page,
|
||||
pages: { resetPasswordReact },
|
||||
}) => {
|
||||
await resetPasswordReact.goto('/confirm_reset_password');
|
||||
|
||||
// Verify its redirected to react reset password page
|
||||
expect(await page.locator('#root').isEnabled()).toBe(true);
|
||||
await resetPasswordReact.resetPasswordHeadingVisible();
|
||||
});
|
||||
|
||||
test('open /reset_password page from /signin', async ({
|
||||
credentials,
|
||||
page,
|
||||
pages: { login },
|
||||
}) => {
|
||||
await login.goto();
|
||||
await login.setEmail(credentials.email);
|
||||
await login.submit();
|
||||
await login.clickForgotPassword();
|
||||
// Verify react page has been loaded - to be enabled when link to react page from sign in is active
|
||||
// await page.waitForSelector('#root');
|
||||
});
|
||||
|
||||
// tests for submission success with leading/trailing whitespace in email has been moved to unit tests
|
||||
|
||||
test('open confirm_reset_password page, click resend', async ({
|
||||
credentials,
|
||||
target,
|
||||
page,
|
||||
pages: { resetPasswordReact },
|
||||
}) => {
|
||||
await resetPasswordReact.goto();
|
||||
|
||||
// Verify react page is loaded
|
||||
await page.waitForSelector('#root');
|
||||
|
||||
await resetPasswordReact.fillEmailToResetPwd(credentials.email);
|
||||
await page.waitForURL(
|
||||
getReactFeatureFlagUrl(target, '/confirm_reset_password')
|
||||
);
|
||||
await resetPasswordReact.confirmResetPasswordHeadingVisible();
|
||||
|
||||
const resendButton = page.getByRole('button', {
|
||||
name: 'Not in inbox or spam folder? Resend',
|
||||
test.describe('severity-1 #smoke', () => {
|
||||
test.describe('reset password react', () => {
|
||||
test.beforeEach(async ({ pages: { configPage } }) => {
|
||||
test.slow();
|
||||
// Ensure that the feature flag is enabled
|
||||
const config = await configPage.getConfig();
|
||||
test.skip(config.showReactApp.resetPasswordRoutes !== true);
|
||||
});
|
||||
await resendButton.waitFor();
|
||||
await resendButton.click();
|
||||
await page.getByText(/Email resent/).waitFor();
|
||||
});
|
||||
|
||||
test('open /reset_password page, enter unknown email, wait for error', async ({
|
||||
target,
|
||||
page,
|
||||
pages: { login, resetPasswordReact },
|
||||
}) => {
|
||||
await resetPasswordReact.goto();
|
||||
test('can reset password', async ({
|
||||
page,
|
||||
target,
|
||||
credentials,
|
||||
context,
|
||||
pages: { login, resetPasswordReact },
|
||||
}) => {
|
||||
await resetPasswordReact.goto();
|
||||
|
||||
// Verify react page is loaded
|
||||
await page.waitForSelector('#root');
|
||||
await resetPasswordReact.fillEmailToResetPwd('email@restmail.net');
|
||||
await page.getByText('Unknown account').waitFor();
|
||||
});
|
||||
// Verify react page has been loaded
|
||||
await page.waitForSelector('#root');
|
||||
|
||||
test('browse directly to page with email on query params', async ({
|
||||
credentials,
|
||||
target,
|
||||
page,
|
||||
pages: { resetPasswordReact },
|
||||
}) => {
|
||||
await resetPasswordReact.goto(undefined, `email=${credentials.email}`);
|
||||
await resetPasswordReact.fillEmailToResetPwd(credentials.email);
|
||||
|
||||
// Verify react page is loaded
|
||||
await page.waitForSelector('#root');
|
||||
// Wait for navigation after email submitted
|
||||
await page.waitForURL(
|
||||
getReactFeatureFlagUrl(target, '/confirm_reset_password')
|
||||
);
|
||||
|
||||
//The email shouldn't be pre-filled
|
||||
const emailInput = await resetPasswordReact.getEmailValue();
|
||||
expect(emailInput).toEqual('');
|
||||
await resetPasswordReact.fillEmailToResetPwd(credentials.email);
|
||||
await page.waitForURL(
|
||||
getReactFeatureFlagUrl(target, '/confirm_reset_password')
|
||||
);
|
||||
await page.waitForSelector('#root');
|
||||
await resetPasswordReact.confirmResetPasswordHeadingVisible();
|
||||
// Verify confirm password reset page rendered
|
||||
await resetPasswordReact.confirmResetPasswordHeadingVisible();
|
||||
|
||||
// We need to append `&showReactApp=true` to reset link in order to enroll in reset password experiment
|
||||
let link = await target.email.waitForEmail(
|
||||
credentials.email,
|
||||
EmailType.recovery,
|
||||
EmailHeader.link
|
||||
);
|
||||
link = `${link}&showReactApp=true`;
|
||||
|
||||
// Open link in a new window
|
||||
const diffPage = await context.newPage();
|
||||
await diffPage.goto(link);
|
||||
|
||||
// Renders the React version of complete password reset page
|
||||
await page.waitForSelector('#root');
|
||||
|
||||
await resetPasswordReact.completeResetPwdHeadingVisible(diffPage);
|
||||
|
||||
// Create and submit new password
|
||||
await resetPasswordReact.submitNewPassword(NEW_PASSWORD, diffPage);
|
||||
|
||||
// Wait for new page to navigate
|
||||
await diffPage.waitForURL(/reset_password_verified/);
|
||||
|
||||
// Wait for initial page to automatically redirect once password is reset
|
||||
await page.waitForURL(`${target.contentServerUrl}/signin`);
|
||||
|
||||
// Verify password reset confirmation page is rendered
|
||||
await resetPasswordReact.resetPwdConfirmedHeadingVisible(diffPage);
|
||||
|
||||
await diffPage.close();
|
||||
|
||||
// Verify initial page redirected to sign in and sign in page rendered
|
||||
await login.emailHeader.waitFor();
|
||||
|
||||
await login.setEmail(credentials.email);
|
||||
await login.clickSubmit();
|
||||
await page.waitForURL(`${target.contentServerUrl}/signin`);
|
||||
|
||||
await login.setPassword(NEW_PASSWORD);
|
||||
await login.clickSubmit();
|
||||
await page.waitForURL(`${target.contentServerUrl}/settings`);
|
||||
|
||||
await page.getByRole('heading', { name: 'Settings', level: 2 }).waitFor();
|
||||
|
||||
// Check that connected service name is not empty!
|
||||
expect(await page.getByTestId('service-name').innerText()).toContain(
|
||||
'Firefox'
|
||||
);
|
||||
|
||||
// Cleanup requires setting this value to correct password
|
||||
credentials.password = NEW_PASSWORD;
|
||||
});
|
||||
|
||||
test('cannot set an invalid password', async ({
|
||||
page,
|
||||
target,
|
||||
credentials,
|
||||
context,
|
||||
pages: { login, resetPasswordReact },
|
||||
}) => {
|
||||
await resetPasswordReact.goto();
|
||||
|
||||
// Verify react page has been loaded
|
||||
await page.waitForSelector('#root');
|
||||
|
||||
await resetPasswordReact.fillEmailToResetPwd(credentials.email);
|
||||
|
||||
// Wait for navigation after email submitted
|
||||
await page.waitForURL(
|
||||
getReactFeatureFlagUrl(target, '/confirm_reset_password')
|
||||
);
|
||||
|
||||
// Verify confirm password reset page rendered
|
||||
await resetPasswordReact.confirmResetPasswordHeadingVisible();
|
||||
|
||||
// We need to append `&showReactApp=true` to reset link in order to enroll in reset password experiment
|
||||
let link = await target.email.waitForEmail(
|
||||
credentials.email,
|
||||
EmailType.recovery,
|
||||
EmailHeader.link
|
||||
);
|
||||
link = `${link}&showReactApp=true`;
|
||||
|
||||
// Open link in a new window
|
||||
const diffPage = await context.newPage();
|
||||
await diffPage.goto(link);
|
||||
|
||||
// Renders the React version of complete password reset page
|
||||
await page.waitForSelector('#root');
|
||||
await resetPasswordReact.completeResetPwdHeadingVisible(diffPage);
|
||||
|
||||
// Attempt to submit short password
|
||||
await resetPasswordReact.submitNewPassword('2short', diffPage);
|
||||
|
||||
await diffPage.getByText('At least 8 characters').waitFor();
|
||||
await expect(
|
||||
diffPage.getByRole('textbox', { name: 'New password' })
|
||||
).toBeFocused();
|
||||
|
||||
// Attempt to submit email as password
|
||||
await resetPasswordReact.submitNewPassword(credentials.email, diffPage);
|
||||
|
||||
await diffPage.getByText('Not your email').waitFor();
|
||||
await expect(
|
||||
diffPage.getByRole('textbox', { name: 'New password' })
|
||||
).toBeFocused();
|
||||
|
||||
// Attempt to submit a common password
|
||||
await resetPasswordReact.submitNewPassword('password', diffPage);
|
||||
|
||||
await diffPage.getByText('Not a commonly used password').waitFor();
|
||||
await expect(
|
||||
diffPage.getByRole('textbox', { name: 'New password' })
|
||||
).toBeFocused();
|
||||
});
|
||||
|
||||
test('visit confirmation screen without initiating reset_password, user is redirected to /reset_password', async ({
|
||||
target,
|
||||
page,
|
||||
pages: { resetPasswordReact },
|
||||
}) => {
|
||||
await resetPasswordReact.goto('/confirm_reset_password');
|
||||
|
||||
// Verify its redirected to react reset password page
|
||||
expect(await page.locator('#root').isEnabled()).toBe(true);
|
||||
await resetPasswordReact.resetPasswordHeadingVisible();
|
||||
});
|
||||
|
||||
test('open /reset_password page from /signin', async ({
|
||||
credentials,
|
||||
page,
|
||||
pages: { login },
|
||||
}) => {
|
||||
await login.goto();
|
||||
await login.setEmail(credentials.email);
|
||||
await login.submit();
|
||||
await login.clickForgotPassword();
|
||||
// Verify react page has been loaded - to be enabled when link to react page from sign in is active
|
||||
// await page.waitForSelector('#root');
|
||||
});
|
||||
|
||||
// tests for submission success with leading/trailing whitespace in email has been moved to unit tests
|
||||
|
||||
test('open confirm_reset_password page, click resend', async ({
|
||||
credentials,
|
||||
target,
|
||||
page,
|
||||
pages: { resetPasswordReact },
|
||||
}) => {
|
||||
await resetPasswordReact.goto();
|
||||
|
||||
// Verify react page is loaded
|
||||
await page.waitForSelector('#root');
|
||||
|
||||
await resetPasswordReact.fillEmailToResetPwd(credentials.email);
|
||||
await page.waitForURL(
|
||||
getReactFeatureFlagUrl(target, '/confirm_reset_password')
|
||||
);
|
||||
await resetPasswordReact.confirmResetPasswordHeadingVisible();
|
||||
|
||||
const resendButton = page.getByRole('button', {
|
||||
name: 'Not in inbox or spam folder? Resend',
|
||||
});
|
||||
await resendButton.waitFor();
|
||||
await resendButton.click();
|
||||
await page.getByText(/Email resent/).waitFor();
|
||||
});
|
||||
|
||||
test('open /reset_password page, enter unknown email, wait for error', async ({
|
||||
target,
|
||||
page,
|
||||
pages: { login, resetPasswordReact },
|
||||
}) => {
|
||||
await resetPasswordReact.goto();
|
||||
|
||||
// Verify react page is loaded
|
||||
await page.waitForSelector('#root');
|
||||
await resetPasswordReact.fillEmailToResetPwd('email@restmail.net');
|
||||
await page.getByText('Unknown account').waitFor();
|
||||
});
|
||||
|
||||
test('browse directly to page with email on query params', async ({
|
||||
credentials,
|
||||
target,
|
||||
page,
|
||||
pages: { resetPasswordReact },
|
||||
}) => {
|
||||
await resetPasswordReact.goto(undefined, `email=${credentials.email}`);
|
||||
|
||||
// Verify react page is loaded
|
||||
await page.waitForSelector('#root');
|
||||
|
||||
//The email shouldn't be pre-filled
|
||||
const emailInput = await resetPasswordReact.getEmailValue();
|
||||
expect(emailInput).toEqual('');
|
||||
await resetPasswordReact.fillEmailToResetPwd(credentials.email);
|
||||
await page.waitForURL(
|
||||
getReactFeatureFlagUrl(target, '/confirm_reset_password')
|
||||
);
|
||||
await page.waitForSelector('#root');
|
||||
await resetPasswordReact.confirmResetPasswordHeadingVisible();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -8,147 +8,150 @@ import { createCustomEventDetail, FirefoxCommand } from '../../lib/channels';
|
|||
|
||||
const PASSWORD = 'passwordzxcv';
|
||||
|
||||
test.describe('signup react', () => {
|
||||
let email;
|
||||
test.beforeEach(async ({ pages: { login, configPage } }) => {
|
||||
test.slow();
|
||||
// Ensure that the feature flag is enabled
|
||||
const config = await configPage.getConfig();
|
||||
test.skip(config.showReactApp.signUpRoutes !== true);
|
||||
test.describe('severity-1 #smoke', () => {
|
||||
test.describe('signup react', () => {
|
||||
let email;
|
||||
test.beforeEach(async ({ pages: { login, configPage } }) => {
|
||||
test.slow();
|
||||
// Ensure that the feature flag is enabled
|
||||
const config = await configPage.getConfig();
|
||||
test.skip(config.showReactApp.signUpRoutes !== true);
|
||||
|
||||
email = login.createEmail('signup_react{id}');
|
||||
});
|
||||
email = login.createEmail('signup_react{id}');
|
||||
});
|
||||
|
||||
test.afterEach(async ({ target }) => {
|
||||
if (email) {
|
||||
// Cleanup any accounts created during the test
|
||||
try {
|
||||
await target.auth.accountDestroy(email, PASSWORD);
|
||||
} catch (e) {
|
||||
// Ignore errors
|
||||
test.afterEach(async ({ target }) => {
|
||||
if (email) {
|
||||
// Cleanup any accounts created during the test
|
||||
try {
|
||||
await target.auth.accountDestroy(email, PASSWORD);
|
||||
} catch (e) {
|
||||
// Ignore errors
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
test('signup web', async ({ page, target, pages: { signupReact } }) => {
|
||||
await signupReact.goto();
|
||||
await signupReact.fillOutEmailFirst(email);
|
||||
await signupReact.fillOutSignupForm(PASSWORD);
|
||||
test('signup web', async ({ page, target, pages: { signupReact } }) => {
|
||||
await signupReact.goto();
|
||||
await signupReact.fillOutEmailFirst(email);
|
||||
await signupReact.fillOutSignupForm(PASSWORD);
|
||||
|
||||
const code = await target.email.waitForEmail(
|
||||
email,
|
||||
EmailType.verifyShortCode,
|
||||
EmailHeader.shortCode
|
||||
);
|
||||
const code = await target.email.waitForEmail(
|
||||
email,
|
||||
EmailType.verifyShortCode,
|
||||
EmailHeader.shortCode
|
||||
);
|
||||
|
||||
await signupReact.fillOutCodeForm(code);
|
||||
await signupReact.fillOutCodeForm(code);
|
||||
|
||||
// Verify logged into settings page
|
||||
await page.waitForURL(/settings/);
|
||||
});
|
||||
// Verify logged into settings page
|
||||
await page.waitForURL(/settings/);
|
||||
});
|
||||
|
||||
test('signup oauth', async ({
|
||||
target,
|
||||
pages: { page, signupReact, relier },
|
||||
}) => {
|
||||
await relier.goto();
|
||||
await relier.clickEmailFirst();
|
||||
test('signup oauth', async ({
|
||||
target,
|
||||
pages: { page, signupReact, relier },
|
||||
}) => {
|
||||
await relier.goto();
|
||||
await relier.clickEmailFirst();
|
||||
|
||||
const { searchParams } = new URL(page.url());
|
||||
searchParams.set('email', email);
|
||||
const { searchParams } = new URL(page.url());
|
||||
searchParams.set('email', email);
|
||||
|
||||
// We want to append the experiment params here, but also keep the original oauth params
|
||||
await signupReact.goto('/oauth/signup', searchParams);
|
||||
await signupReact.fillOutSignupForm(PASSWORD);
|
||||
// We want to append the experiment params here, but also keep the original oauth params
|
||||
await signupReact.goto('/oauth/signup', searchParams);
|
||||
await signupReact.fillOutSignupForm(PASSWORD);
|
||||
|
||||
// TODO: This needs to be uncommented once oauth is redirecting back to relier
|
||||
// const code = await target.email.waitForEmail(
|
||||
// email,
|
||||
// EmailType.verifyShortCode,
|
||||
// EmailHeader.shortCode
|
||||
// );
|
||||
// TODO: This needs to be uncommented once oauth is redirecting back to relier
|
||||
// const code = await target.email.waitForEmail(
|
||||
// email,
|
||||
// EmailType.verifyShortCode,
|
||||
// EmailHeader.shortCode
|
||||
// );
|
||||
|
||||
// await signupReact.fillOutCodeForm(code);
|
||||
// await signupReact.fillOutCodeForm(code);
|
||||
|
||||
// Verify logged in on relier page
|
||||
// expect(await relier.isLoggedIn()).toBe(true);
|
||||
// await page.waitForURL(/settings/);
|
||||
});
|
||||
// Verify logged in on relier page
|
||||
// expect(await relier.isLoggedIn()).toBe(true);
|
||||
// await page.waitForURL(/settings/);
|
||||
});
|
||||
|
||||
test('signup oauth webchannel', async ({
|
||||
page,
|
||||
target,
|
||||
pages: { login, relier, signupReact },
|
||||
}) => {
|
||||
const customEventDetail = createCustomEventDetail(
|
||||
FirefoxCommand.FxAStatus,
|
||||
{
|
||||
capabilities: {
|
||||
choose_what_to_sync: true,
|
||||
engines: ['bookmarks', 'history'],
|
||||
},
|
||||
signedInUser: null,
|
||||
}
|
||||
);
|
||||
/* Disabling this until FXA-8287 is fixed
|
||||
test('signup oauth webchannel', async ({
|
||||
page,
|
||||
target,
|
||||
pages: { login, relier, signupReact },
|
||||
}) => {
|
||||
const customEventDetail = createCustomEventDetail(
|
||||
FirefoxCommand.FxAStatus,
|
||||
{
|
||||
capabilities: {
|
||||
choose_what_to_sync: true,
|
||||
engines: ['bookmarks', 'history'],
|
||||
},
|
||||
signedInUser: null,
|
||||
}
|
||||
);
|
||||
|
||||
await relier.goto('context=oauth_webchannel_v1&automatedBrowser=true');
|
||||
await relier.clickEmailFirst();
|
||||
await relier.goto('context=oauth_webchannel_v1&automatedBrowser=true');
|
||||
await relier.clickEmailFirst();
|
||||
|
||||
await login.respondToWebChannelMessage(customEventDetail);
|
||||
await login.respondToWebChannelMessage(customEventDetail);
|
||||
|
||||
// TODO: CTWS has not been implemented yet, probably better to pull into signupReact page
|
||||
// await login.waitForCWTSEngineHeader();
|
||||
// expect(await login.isCWTSEngineBookmarks()).toBe(true);
|
||||
// expect(await login.isCWTSEngineHistory()).toBe(true);
|
||||
// TODO: CTWS has not been implemented yet, probably better to pull into signupReact page
|
||||
// await login.waitForCWTSEngineHeader();
|
||||
// expect(await login.isCWTSEngineBookmarks()).toBe(true);
|
||||
// expect(await login.isCWTSEngineHistory()).toBe(true);
|
||||
|
||||
const { searchParams } = new URL(page.url());
|
||||
searchParams.set('email', email);
|
||||
const { searchParams } = new URL(page.url());
|
||||
searchParams.set('email', email);
|
||||
|
||||
// We want to append the experiment params here, but also keep the original oauth params
|
||||
await signupReact.goto('/oauth/signup', searchParams);
|
||||
await signupReact.fillOutSignupForm(PASSWORD);
|
||||
// We want to append the experiment params here, but also keep the original oauth params
|
||||
await signupReact.goto('/oauth/signup', searchParams);
|
||||
await signupReact.fillOutSignupForm(PASSWORD);
|
||||
|
||||
// TODO: This needs to be implemented as well
|
||||
// const code = await target.email.waitForEmail(
|
||||
// email,
|
||||
// EmailType.verifyShortCode,
|
||||
// EmailHeader.shortCode
|
||||
// );
|
||||
//
|
||||
// await signupReact.fillOutCodeForm(code);
|
||||
// await login.checkWebChannelMessage(FirefoxCommand.OAuthLogin);
|
||||
});
|
||||
// TODO: This needs to be implemented as well
|
||||
// const code = await target.email.waitForEmail(
|
||||
// email,
|
||||
// EmailType.verifyShortCode,
|
||||
// EmailHeader.shortCode
|
||||
// );
|
||||
//
|
||||
// await signupReact.fillOutCodeForm(code);
|
||||
// await login.checkWebChannelMessage(FirefoxCommand.OAuthLogin);
|
||||
});*/
|
||||
|
||||
test('signup sync', async ({ target }) => {
|
||||
test.slow();
|
||||
const syncBrowserPages = await newPagesForSync(target);
|
||||
const { login, signupReact } = syncBrowserPages;
|
||||
test('signup sync', async ({ target }) => {
|
||||
test.slow();
|
||||
const syncBrowserPages = await newPagesForSync(target);
|
||||
const { login, signupReact } = syncBrowserPages;
|
||||
|
||||
email = login.createEmail('sync{id}');
|
||||
email = login.createEmail('sync{id}');
|
||||
|
||||
await signupReact.goto(
|
||||
'/',
|
||||
new URLSearchParams({
|
||||
context: 'fx_desktop_v3',
|
||||
service: 'sync',
|
||||
action: 'email',
|
||||
})
|
||||
);
|
||||
await signupReact.goto(
|
||||
'/',
|
||||
new URLSearchParams({
|
||||
context: 'fx_desktop_v3',
|
||||
service: 'sync',
|
||||
action: 'email',
|
||||
})
|
||||
);
|
||||
|
||||
await signupReact.fillOutEmailFirst(email);
|
||||
await signupReact.fillOutSignupForm(PASSWORD);
|
||||
await signupReact.fillOutEmailFirst(email);
|
||||
await signupReact.fillOutSignupForm(PASSWORD);
|
||||
|
||||
const code = await target.email.waitForEmail(
|
||||
email,
|
||||
EmailType.verifyShortCode,
|
||||
EmailHeader.shortCode
|
||||
);
|
||||
const code = await target.email.waitForEmail(
|
||||
email,
|
||||
EmailType.verifyShortCode,
|
||||
EmailHeader.shortCode
|
||||
);
|
||||
|
||||
await signupReact.fillOutCodeForm(code);
|
||||
await signupReact.fillOutCodeForm(code);
|
||||
|
||||
// TODO Uncomment once sync is working
|
||||
// expect(await connectAnotherDevice.fxaConnected.isVisible()).toBeTruthy();
|
||||
// TODO Uncomment once sync is working
|
||||
// expect(await connectAnotherDevice.fxaConnected.isVisible()).toBeTruthy();
|
||||
|
||||
await syncBrowserPages.browser?.close();
|
||||
await syncBrowserPages.browser?.close();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -9,54 +9,56 @@ import { getReactFeatureFlagUrl } from '../../lib/react-flag';
|
|||
test.describe.configure({ mode: 'parallel' });
|
||||
let syncBrowserPages;
|
||||
|
||||
test.describe('Firefox Desktop Sync v3 reset password react', () => {
|
||||
test.beforeEach(async ({ target, pages: { configPage } }) => {
|
||||
test.slow();
|
||||
// Ensure that the feature flag is enabled
|
||||
const config = await configPage.getConfig();
|
||||
test.skip(config.showReactApp.resetPasswordRoutes !== true);
|
||||
test.describe('severity-1 #smoke', () => {
|
||||
test.describe('Firefox Desktop Sync v3 reset password react', () => {
|
||||
test.beforeEach(async ({ target, pages: { configPage } }) => {
|
||||
test.slow();
|
||||
// Ensure that the feature flag is enabled
|
||||
const config = await configPage.getConfig();
|
||||
test.skip(config.showReactApp.resetPasswordRoutes !== true);
|
||||
|
||||
syncBrowserPages = await newPagesForSync(target);
|
||||
});
|
||||
syncBrowserPages = await newPagesForSync(target);
|
||||
});
|
||||
|
||||
test('reset pw for sync user', async ({ credentials, target }) => {
|
||||
const { page, resetPasswordReact } = syncBrowserPages;
|
||||
await page.goto(
|
||||
getReactFeatureFlagUrl(
|
||||
target,
|
||||
'/reset_password',
|
||||
'context=fx_desktop_v3&service=sync'
|
||||
)
|
||||
);
|
||||
test('reset pw for sync user', async ({ credentials, target }) => {
|
||||
const { page, resetPasswordReact } = syncBrowserPages;
|
||||
await page.goto(
|
||||
getReactFeatureFlagUrl(
|
||||
target,
|
||||
'/reset_password',
|
||||
'context=fx_desktop_v3&service=sync'
|
||||
)
|
||||
);
|
||||
|
||||
// Verify react page has been loaded
|
||||
await page.waitForSelector('#root');
|
||||
// Verify react page has been loaded
|
||||
await page.waitForSelector('#root');
|
||||
|
||||
// Check that the sync relier is in the heading
|
||||
await page
|
||||
.getByRole('heading', {
|
||||
name: /Firefox Sync/,
|
||||
})
|
||||
.waitFor();
|
||||
// Check that the sync relier is in the heading
|
||||
await page
|
||||
.getByRole('heading', {
|
||||
name: /Firefox Sync/,
|
||||
})
|
||||
.waitFor();
|
||||
|
||||
await resetPasswordReact.fillEmailToResetPwd(credentials.email);
|
||||
await resetPasswordReact.fillEmailToResetPwd(credentials.email);
|
||||
|
||||
// We need to append `&showReactApp=true` to reset link in order to enroll in reset password experiment
|
||||
let link = await target.email.waitForEmail(
|
||||
credentials.email,
|
||||
EmailType.recovery,
|
||||
EmailHeader.link
|
||||
);
|
||||
link = `${link}&showReactApp=true`;
|
||||
// We need to append `&showReactApp=true` to reset link in order to enroll in reset password experiment
|
||||
let link = await target.email.waitForEmail(
|
||||
credentials.email,
|
||||
EmailType.recovery,
|
||||
EmailHeader.link
|
||||
);
|
||||
link = `${link}&showReactApp=true`;
|
||||
|
||||
await page.goto(link);
|
||||
await page.goto(link);
|
||||
|
||||
await resetPasswordReact.submitNewPassword('Newpassword@');
|
||||
await page.waitForURL(/reset_password_verified/);
|
||||
await resetPasswordReact.submitNewPassword('Newpassword@');
|
||||
await page.waitForURL(/reset_password_verified/);
|
||||
|
||||
await resetPasswordReact.resetPwdConfirmedHeadingVisible();
|
||||
await resetPasswordReact.resetPwdConfirmedHeadingVisible();
|
||||
|
||||
// Update credentials file so that account can be deleted as part of test cleanup
|
||||
credentials.password = 'Newpassword@';
|
||||
// Update credentials file so that account can be deleted as part of test cleanup
|
||||
credentials.password = 'Newpassword@';
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -1,145 +1,151 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
import { test, expect } from '../../lib/fixtures/standard';
|
||||
import { EmailHeader, EmailType } from '../../lib/email';
|
||||
|
||||
const NEW_PASSWORD = 'passwordzxcv';
|
||||
|
||||
test.describe('Reset password current', () => {
|
||||
test.beforeEach(async ({ pages: { configPage } }) => {
|
||||
test.slow();
|
||||
test.describe('severity-2 #smoke', () => {
|
||||
test.describe('Reset password current', () => {
|
||||
test.beforeEach(async ({ pages: { configPage } }) => {
|
||||
test.slow();
|
||||
|
||||
const config = await configPage.getConfig();
|
||||
test.skip(config.showReactApp.resetPasswordRoutes === true);
|
||||
});
|
||||
const config = await configPage.getConfig();
|
||||
test.skip(config.showReactApp.resetPasswordRoutes === true);
|
||||
});
|
||||
|
||||
test('can reset password', async ({
|
||||
page,
|
||||
target,
|
||||
credentials,
|
||||
context,
|
||||
pages: { login, resetPassword, settings },
|
||||
}) => {
|
||||
await page.goto(`${target.contentServerUrl}/reset_password`);
|
||||
test('can reset password', async ({
|
||||
page,
|
||||
target,
|
||||
credentials,
|
||||
context,
|
||||
pages: { login, resetPassword, settings },
|
||||
}) => {
|
||||
await page.goto(`${target.contentServerUrl}/reset_password`);
|
||||
|
||||
// Verify backbone page has been loaded
|
||||
await page.waitForSelector('#stage');
|
||||
// Verify backbone page has been loaded
|
||||
await page.waitForSelector('#stage');
|
||||
|
||||
await resetPassword.fillOutResetPassword(credentials.email);
|
||||
await resetPassword.fillOutResetPassword(credentials.email);
|
||||
|
||||
// Verify confirm password reset page has rendered
|
||||
await resetPassword.confirmResetPasswordHeader();
|
||||
// Verify confirm password reset page has rendered
|
||||
await resetPassword.confirmResetPasswordHeader();
|
||||
|
||||
const link = await target.email.waitForEmail(
|
||||
credentials.email,
|
||||
EmailType.recovery,
|
||||
EmailHeader.link
|
||||
);
|
||||
const link = await target.email.waitForEmail(
|
||||
credentials.email,
|
||||
EmailType.recovery,
|
||||
EmailHeader.link
|
||||
);
|
||||
|
||||
// Open link in a new window
|
||||
const diffPage = await context.newPage();
|
||||
await diffPage.goto(link);
|
||||
// Open link in a new window
|
||||
const diffPage = await context.newPage();
|
||||
await diffPage.goto(link);
|
||||
|
||||
await resetPassword.completeResetPasswordHeader(diffPage);
|
||||
await resetPassword.completeResetPasswordHeader(diffPage);
|
||||
|
||||
await resetPassword.resetNewPassword(NEW_PASSWORD, diffPage);
|
||||
await resetPassword.resetNewPassword(NEW_PASSWORD, diffPage);
|
||||
|
||||
await page.getByRole('heading', { name: 'Settings', level: 2 }).waitFor();
|
||||
await page.getByRole('heading', { name: 'Settings', level: 2 }).waitFor();
|
||||
|
||||
await diffPage
|
||||
.getByRole('heading', { name: 'Settings', level: 2 })
|
||||
.waitFor();
|
||||
await diffPage
|
||||
.getByRole('heading', { name: 'Settings', level: 2 })
|
||||
.waitFor();
|
||||
|
||||
await diffPage.close();
|
||||
await settings.signOut();
|
||||
await diffPage.close();
|
||||
await settings.signOut();
|
||||
|
||||
// Verify that new password can be used to log in
|
||||
await login.setEmail(credentials.email);
|
||||
await login.submit();
|
||||
await login.setPassword(NEW_PASSWORD);
|
||||
await login.submit();
|
||||
// Verify that new password can be used to log in
|
||||
await login.setEmail(credentials.email);
|
||||
await login.submit();
|
||||
await login.setPassword(NEW_PASSWORD);
|
||||
await login.submit();
|
||||
|
||||
await page.getByRole('heading', { name: 'Settings', level: 2 }).waitFor();
|
||||
await page.getByRole('heading', { name: 'Settings', level: 2 }).waitFor();
|
||||
|
||||
// Cleanup requires setting this value to correct password
|
||||
credentials.password = NEW_PASSWORD;
|
||||
});
|
||||
// Cleanup requires setting this value to correct password
|
||||
credentials.password = NEW_PASSWORD;
|
||||
});
|
||||
|
||||
test('visit confirmation screen without initiating reset_password, user is redirected to /reset_password', async ({
|
||||
target,
|
||||
page,
|
||||
pages: { resetPassword },
|
||||
}) => {
|
||||
await page.goto(
|
||||
`${target.contentServerUrl}/confirm_reset_password?showReactApp=false`
|
||||
);
|
||||
test('visit confirmation screen without initiating reset_password, user is redirected to /reset_password', async ({
|
||||
target,
|
||||
page,
|
||||
pages: { resetPassword },
|
||||
}) => {
|
||||
await page.goto(
|
||||
`${target.contentServerUrl}/confirm_reset_password?showReactApp=false`
|
||||
);
|
||||
|
||||
// Verify its redirected to reset password page
|
||||
await resetPassword.resetPasswordHeader();
|
||||
});
|
||||
// Verify its redirected to reset password page
|
||||
await resetPassword.resetPasswordHeader();
|
||||
});
|
||||
|
||||
test('open /reset_password page from /signin', async ({
|
||||
credentials,
|
||||
pages: { login },
|
||||
}) => {
|
||||
await login.goto();
|
||||
await login.setEmail(credentials.email);
|
||||
await login.submit();
|
||||
await login.clickForgotPassword();
|
||||
});
|
||||
test('open /reset_password page from /signin', async ({
|
||||
credentials,
|
||||
pages: { login },
|
||||
}) => {
|
||||
await login.goto();
|
||||
await login.setEmail(credentials.email);
|
||||
await login.submit();
|
||||
await login.clickForgotPassword();
|
||||
});
|
||||
|
||||
test('enter an email with leading/trailing whitespace', async ({
|
||||
credentials,
|
||||
target,
|
||||
page,
|
||||
pages: { login, resetPassword },
|
||||
}) => {
|
||||
await page.goto(`${target.contentServerUrl}/reset_password`);
|
||||
await resetPassword.fillOutResetPassword(' ' + credentials.email);
|
||||
await resetPassword.confirmResetPasswordHeader();
|
||||
test('enter an email with leading/trailing whitespace', async ({
|
||||
credentials,
|
||||
target,
|
||||
page,
|
||||
pages: { login, resetPassword },
|
||||
}) => {
|
||||
await page.goto(`${target.contentServerUrl}/reset_password`);
|
||||
await resetPassword.fillOutResetPassword(' ' + credentials.email);
|
||||
await resetPassword.confirmResetPasswordHeader();
|
||||
|
||||
await page.goto(`${target.contentServerUrl}/reset_password`);
|
||||
await resetPassword.fillOutResetPassword(credentials.email + ' ');
|
||||
await resetPassword.confirmResetPasswordHeader();
|
||||
});
|
||||
await page.goto(`${target.contentServerUrl}/reset_password`);
|
||||
await resetPassword.fillOutResetPassword(credentials.email + ' ');
|
||||
await resetPassword.confirmResetPasswordHeader();
|
||||
});
|
||||
|
||||
test('open confirm_reset_password page, click resend', async ({
|
||||
credentials,
|
||||
target,
|
||||
page,
|
||||
pages: { resetPassword },
|
||||
}) => {
|
||||
await page.goto(`${target.contentServerUrl}/reset_password`);
|
||||
await resetPassword.fillOutResetPassword(credentials.email);
|
||||
await resetPassword.clickResend();
|
||||
expect(await resetPassword.resendSuccessMessage()).toContain(
|
||||
'Email resent. Add accounts@firefox.com to your contacts to ensure a smooth delivery.'
|
||||
);
|
||||
});
|
||||
test('open confirm_reset_password page, click resend', async ({
|
||||
credentials,
|
||||
target,
|
||||
page,
|
||||
pages: { resetPassword },
|
||||
}) => {
|
||||
await page.goto(`${target.contentServerUrl}/reset_password`);
|
||||
await resetPassword.fillOutResetPassword(credentials.email);
|
||||
await resetPassword.clickResend();
|
||||
expect(await resetPassword.resendSuccessMessage()).toContain(
|
||||
'Email resent. Add accounts@firefox.com to your contacts to ensure a smooth delivery.'
|
||||
);
|
||||
});
|
||||
|
||||
test('open /reset_password page, enter unknown email, wait for error', async ({
|
||||
target,
|
||||
page,
|
||||
pages: { login, resetPassword },
|
||||
}) => {
|
||||
await page.goto(`${target.contentServerUrl}/reset_password`);
|
||||
await login.setEmail('email@restmail.net');
|
||||
await resetPassword.clickBeginReset();
|
||||
expect(await resetPassword.unknownAccountError()).toContain(
|
||||
'Unknown account.'
|
||||
);
|
||||
});
|
||||
test('open /reset_password page, enter unknown email, wait for error', async ({
|
||||
target,
|
||||
page,
|
||||
pages: { login, resetPassword },
|
||||
}) => {
|
||||
await page.goto(`${target.contentServerUrl}/reset_password`);
|
||||
await login.setEmail('email@restmail.net');
|
||||
await resetPassword.clickBeginReset();
|
||||
expect(await resetPassword.unknownAccountError()).toContain(
|
||||
'Unknown account.'
|
||||
);
|
||||
});
|
||||
|
||||
test('browse directly to page with email on query params', async ({
|
||||
credentials,
|
||||
target,
|
||||
page,
|
||||
pages: { resetPassword },
|
||||
}) => {
|
||||
const url = `${target.contentServerUrl}/reset_password?email=${credentials.email}`;
|
||||
await page.goto(url);
|
||||
test('browse directly to page with email on query params', async ({
|
||||
credentials,
|
||||
target,
|
||||
page,
|
||||
pages: { resetPassword },
|
||||
}) => {
|
||||
const url = `${target.contentServerUrl}/reset_password?email=${credentials.email}`;
|
||||
await page.goto(url);
|
||||
|
||||
//The email shouldn't be pre-filled
|
||||
expect(await resetPassword.getEmailValue()).toBeEmpty();
|
||||
await resetPassword.fillOutResetPassword(credentials.email);
|
||||
await resetPassword.confirmResetPasswordHeader();
|
||||
//The email shouldn't be pre-filled
|
||||
expect(await resetPassword.getEmailValue()).toBeEmpty();
|
||||
await resetPassword.fillOutResetPassword(credentials.email);
|
||||
await resetPassword.confirmResetPasswordHeader();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -1,6 +1,10 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
import { test, expect } from '../../lib/fixtures/standard';
|
||||
|
||||
test.describe('severity-2 #smoke', () => {
|
||||
test.describe('severity-1 #smoke', () => {
|
||||
// https://testrail.stage.mozaws.net/index.php?/cases/view/1293498
|
||||
test('settings avatar drop-down #1293498', async ({
|
||||
credentials,
|
||||
|
|
|
@ -1,161 +1,167 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
import { test, expect } from '../../lib/fixtures/standard';
|
||||
let newEmail;
|
||||
|
||||
test.describe('change primary email tests', () => {
|
||||
test.beforeEach(
|
||||
async ({ credentials, pages: { settings, secondaryEmail } }) => {
|
||||
test.slow();
|
||||
await settings.goto();
|
||||
await settings.secondaryEmail.clickAdd();
|
||||
newEmail = credentials.email.replace(/(\w+)/, '$1_alt');
|
||||
await secondaryEmail.addAndVerify(newEmail);
|
||||
await settings.waitForAlertBar();
|
||||
await settings.secondaryEmail.clickMakePrimary();
|
||||
}
|
||||
);
|
||||
|
||||
test('change primary email and login', async ({
|
||||
credentials,
|
||||
page,
|
||||
pages: { login, settings },
|
||||
}) => {
|
||||
await settings.signOut();
|
||||
|
||||
// Sign in with old primary email fails
|
||||
await login.setEmail(credentials.email);
|
||||
await page.locator('button[type=submit]').click();
|
||||
await login.setPassword(credentials.password);
|
||||
await page.locator('button[type=submit]').click();
|
||||
expect(await login.signInError()).toContain(
|
||||
'Primary account email required for sign-in'
|
||||
test.describe('severity-1 #smoke', () => {
|
||||
test.describe('change primary email tests', () => {
|
||||
test.beforeEach(
|
||||
async ({ credentials, pages: { settings, secondaryEmail } }) => {
|
||||
test.slow();
|
||||
await settings.goto();
|
||||
await settings.secondaryEmail.clickAdd();
|
||||
newEmail = credentials.email.replace(/(\w+)/, '$1_alt');
|
||||
await secondaryEmail.addAndVerify(newEmail);
|
||||
await settings.waitForAlertBar();
|
||||
await settings.secondaryEmail.clickMakePrimary();
|
||||
}
|
||||
);
|
||||
|
||||
// Success signing in with New email
|
||||
await login.useDifferentAccountLink();
|
||||
await login.login(newEmail, credentials.password);
|
||||
const primary = await settings.primaryEmail.statusText();
|
||||
expect(primary).toEqual(newEmail);
|
||||
});
|
||||
|
||||
test('change primary email, password and login', async ({
|
||||
credentials,
|
||||
page,
|
||||
pages: { settings, changePassword, login },
|
||||
}) => {
|
||||
const newPassword = credentials.password + '@@2';
|
||||
await settings.password.clickChange();
|
||||
await changePassword.setCurrentPassword(credentials.password);
|
||||
await changePassword.setNewPassword(newPassword);
|
||||
await changePassword.setConfirmPassword(newPassword);
|
||||
await changePassword.submit();
|
||||
await settings.signOut();
|
||||
|
||||
// Sign in with old password
|
||||
await login.setEmail(newEmail);
|
||||
await page.locator('button[type=submit]').click();
|
||||
await login.setPassword(credentials.password);
|
||||
await page.locator('button[type=submit]').click();
|
||||
expect(await login.getTooltipError()).toContain('Incorrect password');
|
||||
|
||||
// Sign in with new password
|
||||
credentials.password = newPassword;
|
||||
await login.setPassword(credentials.password);
|
||||
await login.submit();
|
||||
const primaryEmail = await settings.primaryEmail.statusText();
|
||||
expect(primaryEmail).toEqual(newEmail);
|
||||
});
|
||||
|
||||
test('change primary email, change password, login, change email and login', async ({
|
||||
credentials,
|
||||
pages: { settings, changePassword, login },
|
||||
}) => {
|
||||
const newPassword = credentials.password + '@@4';
|
||||
await settings.password.clickChange();
|
||||
await changePassword.setCurrentPassword(credentials.password);
|
||||
await changePassword.setNewPassword(newPassword);
|
||||
await changePassword.setConfirmPassword(newPassword);
|
||||
await changePassword.submit();
|
||||
await settings.signOut();
|
||||
|
||||
// Sign in with new password
|
||||
credentials.password = newPassword;
|
||||
await login.login(newEmail, credentials.password);
|
||||
|
||||
// Change back the primary email again
|
||||
await settings.secondaryEmail.clickMakePrimary();
|
||||
await settings.signOut();
|
||||
|
||||
// Login with primary email and new password
|
||||
await login.login(credentials.email, credentials.password);
|
||||
const primaryEmail = await settings.primaryEmail.statusText();
|
||||
expect(primaryEmail).toEqual(credentials.email);
|
||||
});
|
||||
|
||||
test('can change primary email, delete account', async ({
|
||||
credentials,
|
||||
page,
|
||||
pages: { settings, deleteAccount, login, secondaryEmail },
|
||||
}) => {
|
||||
// Click delete account
|
||||
await settings.clickDeleteAccount();
|
||||
await deleteAccount.checkAllBoxes();
|
||||
await deleteAccount.clickContinue();
|
||||
|
||||
// Enter the correct password
|
||||
await deleteAccount.setPassword(credentials.password);
|
||||
await deleteAccount.submit();
|
||||
|
||||
// // Try creating a new account with the same secondary email as previous account and new password
|
||||
await login.fillOutFirstSignUp(newEmail, credentials.password);
|
||||
expect(await settings.alertBarText()).toContain(
|
||||
'Account confirmed successfully'
|
||||
);
|
||||
const primaryEmail = await settings.primaryEmail.statusText();
|
||||
expect(primaryEmail).toEqual(newEmail);
|
||||
});
|
||||
});
|
||||
|
||||
test.describe('change primary - unblock', () => {
|
||||
test.beforeEach(
|
||||
async ({ credentials, pages: { settings, secondaryEmail } }) => {
|
||||
test.slow();
|
||||
await settings.goto();
|
||||
await settings.secondaryEmail.clickAdd();
|
||||
const newEmail = `blocked${Math.floor(
|
||||
Math.random() * 100000
|
||||
)}@restmail.net`;
|
||||
await secondaryEmail.addAndVerify(newEmail);
|
||||
await settings.secondaryEmail.clickMakePrimary();
|
||||
credentials.email = newEmail;
|
||||
test('change primary email and login', async ({
|
||||
credentials,
|
||||
page,
|
||||
pages: { login, settings },
|
||||
}) => {
|
||||
await settings.signOut();
|
||||
}
|
||||
);
|
||||
|
||||
test('change primary email, get blocked with invalid password, redirect enter password page', async ({
|
||||
credentials,
|
||||
pages: { login },
|
||||
}) => {
|
||||
const invalidPassword = credentials.password + '@@2';
|
||||
await login.login(credentials.email, invalidPassword);
|
||||
// Sign in with old primary email fails
|
||||
await login.setEmail(credentials.email);
|
||||
await page.locator('button[type=submit]').click();
|
||||
await login.setPassword(credentials.password);
|
||||
await page.locator('button[type=submit]').click();
|
||||
expect(await login.signInError()).toContain(
|
||||
'Primary account email required for sign-in'
|
||||
);
|
||||
|
||||
// Fill out unblock
|
||||
await login.unblock(credentials.email);
|
||||
// Success signing in with New email
|
||||
await login.useDifferentAccountLink();
|
||||
await login.login(newEmail, credentials.password);
|
||||
const primary = await settings.primaryEmail.statusText();
|
||||
expect(primary).toEqual(newEmail);
|
||||
});
|
||||
|
||||
// Verify the incorrect password error
|
||||
expect(await login.signInError()).toContain('Incorrect password');
|
||||
test('change primary email, password and login', async ({
|
||||
credentials,
|
||||
page,
|
||||
pages: { settings, changePassword, login },
|
||||
}) => {
|
||||
const newPassword = credentials.password + '@@2';
|
||||
await settings.password.clickChange();
|
||||
await changePassword.setCurrentPassword(credentials.password);
|
||||
await changePassword.setNewPassword(newPassword);
|
||||
await changePassword.setConfirmPassword(newPassword);
|
||||
await changePassword.submit();
|
||||
await settings.signOut();
|
||||
|
||||
// Sign in with old password
|
||||
await login.setEmail(newEmail);
|
||||
await page.locator('button[type=submit]').click();
|
||||
await login.setPassword(credentials.password);
|
||||
await page.locator('button[type=submit]').click();
|
||||
expect(await login.getTooltipError()).toContain('Incorrect password');
|
||||
|
||||
// Sign in with new password
|
||||
credentials.password = newPassword;
|
||||
await login.setPassword(credentials.password);
|
||||
await login.submit();
|
||||
const primaryEmail = await settings.primaryEmail.statusText();
|
||||
expect(primaryEmail).toEqual(newEmail);
|
||||
});
|
||||
|
||||
test('change primary email, change password, login, change email and login', async ({
|
||||
credentials,
|
||||
pages: { settings, changePassword, login },
|
||||
}) => {
|
||||
const newPassword = credentials.password + '@@4';
|
||||
await settings.password.clickChange();
|
||||
await changePassword.setCurrentPassword(credentials.password);
|
||||
await changePassword.setNewPassword(newPassword);
|
||||
await changePassword.setConfirmPassword(newPassword);
|
||||
await changePassword.submit();
|
||||
await settings.signOut();
|
||||
|
||||
// Sign in with new password
|
||||
credentials.password = newPassword;
|
||||
await login.login(newEmail, credentials.password);
|
||||
|
||||
// Change back the primary email again
|
||||
await settings.secondaryEmail.clickMakePrimary();
|
||||
await settings.signOut();
|
||||
|
||||
// Login with primary email and new password
|
||||
await login.login(credentials.email, credentials.password);
|
||||
const primaryEmail = await settings.primaryEmail.statusText();
|
||||
expect(primaryEmail).toEqual(credentials.email);
|
||||
});
|
||||
|
||||
test('can change primary email, delete account', async ({
|
||||
credentials,
|
||||
page,
|
||||
pages: { settings, deleteAccount, login, secondaryEmail },
|
||||
}) => {
|
||||
// Click delete account
|
||||
await settings.clickDeleteAccount();
|
||||
await deleteAccount.checkAllBoxes();
|
||||
await deleteAccount.clickContinue();
|
||||
|
||||
// Enter the correct password
|
||||
await deleteAccount.setPassword(credentials.password);
|
||||
await deleteAccount.submit();
|
||||
|
||||
// // Try creating a new account with the same secondary email as previous account and new password
|
||||
await login.fillOutFirstSignUp(newEmail, credentials.password);
|
||||
expect(await settings.alertBarText()).toContain(
|
||||
'Account confirmed successfully'
|
||||
);
|
||||
const primaryEmail = await settings.primaryEmail.statusText();
|
||||
expect(primaryEmail).toEqual(newEmail);
|
||||
});
|
||||
});
|
||||
|
||||
test('can change primary email, get blocked with valid password, redirect settings page', async ({
|
||||
credentials,
|
||||
page,
|
||||
pages: { settings, login },
|
||||
}) => {
|
||||
await login.login(credentials.email, credentials.password);
|
||||
test.describe('change primary - unblock', () => {
|
||||
test.beforeEach(
|
||||
async ({ credentials, pages: { settings, secondaryEmail } }) => {
|
||||
test.slow();
|
||||
await settings.goto();
|
||||
await settings.secondaryEmail.clickAdd();
|
||||
const newEmail = `blocked${Math.floor(
|
||||
Math.random() * 100000
|
||||
)}@restmail.net`;
|
||||
await secondaryEmail.addAndVerify(newEmail);
|
||||
await settings.secondaryEmail.clickMakePrimary();
|
||||
credentials.email = newEmail;
|
||||
await settings.signOut();
|
||||
}
|
||||
);
|
||||
|
||||
// Fill out unblock
|
||||
await login.unblock(credentials.email);
|
||||
test('change primary email, get blocked with invalid password, redirect enter password page', async ({
|
||||
credentials,
|
||||
pages: { login },
|
||||
}) => {
|
||||
const invalidPassword = credentials.password + '@@2';
|
||||
await login.login(credentials.email, invalidPassword);
|
||||
|
||||
// Verify settings url redirected
|
||||
expect(page.url()).toBe(settings.url);
|
||||
// Fill out unblock
|
||||
await login.unblock(credentials.email);
|
||||
|
||||
// Verify the incorrect password error
|
||||
expect(await login.signInError()).toContain('Incorrect password');
|
||||
});
|
||||
|
||||
test('can change primary email, get blocked with valid password, redirect settings page', async ({
|
||||
credentials,
|
||||
page,
|
||||
pages: { settings, login },
|
||||
}) => {
|
||||
await login.login(credentials.email, credentials.password);
|
||||
|
||||
// Fill out unblock
|
||||
await login.unblock(credentials.email);
|
||||
|
||||
// Verify settings url redirected
|
||||
expect(page.url()).toBe(settings.url);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -1,101 +1,107 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
import { test, expect } from '../../lib/fixtures/standard';
|
||||
let newPassword;
|
||||
|
||||
test.describe('change password tests', () => {
|
||||
test.beforeEach(async ({ pages: { settings }, credentials }) => {
|
||||
newPassword = credentials.password + '@@2';
|
||||
await settings.goto();
|
||||
await settings.password.clickChange();
|
||||
});
|
||||
test.describe('severity-1 #smoke', () => {
|
||||
test.describe('change password tests', () => {
|
||||
test.beforeEach(async ({ pages: { settings }, credentials }) => {
|
||||
newPassword = credentials.password + '@@2';
|
||||
await settings.goto();
|
||||
await settings.password.clickChange();
|
||||
});
|
||||
|
||||
test('change password with an incorrect old password', async ({
|
||||
pages: { changePassword },
|
||||
}) => {
|
||||
test.slow();
|
||||
// Enter incorrect old password and verify the tooltip error
|
||||
await changePassword.fillOutChangePassword(
|
||||
'Incorrect Password',
|
||||
newPassword
|
||||
);
|
||||
await changePassword.clickSignIn();
|
||||
expect(await changePassword.changePasswordTooltip()).toContain(
|
||||
'Incorrect password'
|
||||
);
|
||||
});
|
||||
test('change password with an incorrect old password', async ({
|
||||
pages: { changePassword },
|
||||
}) => {
|
||||
test.slow();
|
||||
// Enter incorrect old password and verify the tooltip error
|
||||
await changePassword.fillOutChangePassword(
|
||||
'Incorrect Password',
|
||||
newPassword
|
||||
);
|
||||
await changePassword.clickSignIn();
|
||||
expect(await changePassword.changePasswordTooltip()).toContain(
|
||||
'Incorrect password'
|
||||
);
|
||||
});
|
||||
|
||||
test('change password with a correct password', async ({
|
||||
pages: { settings, changePassword, login },
|
||||
credentials,
|
||||
}) => {
|
||||
test.slow();
|
||||
// Enter the correct old password and verify that change password is successful
|
||||
await changePassword.fillOutChangePassword(
|
||||
credentials.password,
|
||||
newPassword
|
||||
);
|
||||
await changePassword.submit();
|
||||
test('change password with a correct password', async ({
|
||||
pages: { settings, changePassword, login },
|
||||
credentials,
|
||||
}) => {
|
||||
test.slow();
|
||||
// Enter the correct old password and verify that change password is successful
|
||||
await changePassword.fillOutChangePassword(
|
||||
credentials.password,
|
||||
newPassword
|
||||
);
|
||||
await changePassword.submit();
|
||||
|
||||
// Sign out and login with new password
|
||||
await settings.signOut();
|
||||
credentials.password = newPassword;
|
||||
await login.setEmail(credentials.email);
|
||||
await changePassword.clickSignIn();
|
||||
await login.setPassword(credentials.password);
|
||||
await login.submit();
|
||||
const primaryEmail = await settings.primaryEmail.statusText();
|
||||
expect(primaryEmail).toEqual(credentials.email);
|
||||
});
|
||||
// Sign out and login with new password
|
||||
await settings.signOut();
|
||||
credentials.password = newPassword;
|
||||
await login.setEmail(credentials.email);
|
||||
await changePassword.clickSignIn();
|
||||
await login.setPassword(credentials.password);
|
||||
await login.submit();
|
||||
const primaryEmail = await settings.primaryEmail.statusText();
|
||||
expect(primaryEmail).toEqual(credentials.email);
|
||||
});
|
||||
|
||||
test('new password validation', async ({
|
||||
pages: { changePassword },
|
||||
credentials,
|
||||
}) => {
|
||||
// Short password
|
||||
await changePassword.setNewPassword('short');
|
||||
expect(await changePassword.passwordLengthError()).toBe(true);
|
||||
test('new password validation', async ({
|
||||
pages: { changePassword },
|
||||
credentials,
|
||||
}) => {
|
||||
// Short password
|
||||
await changePassword.setNewPassword('short');
|
||||
expect(await changePassword.passwordLengthError()).toBe(true);
|
||||
|
||||
// Password same as email
|
||||
await changePassword.setNewPassword(credentials.email);
|
||||
expect(await changePassword.passwordSameAsEmailError()).toBe(true);
|
||||
// Password same as email
|
||||
await changePassword.setNewPassword(credentials.email);
|
||||
expect(await changePassword.passwordSameAsEmailError()).toBe(true);
|
||||
|
||||
// Set a common password
|
||||
await changePassword.setNewPassword('passwords');
|
||||
expect(await changePassword.commonPasswordError()).toBe(true);
|
||||
// Set a common password
|
||||
await changePassword.setNewPassword('passwords');
|
||||
expect(await changePassword.commonPasswordError()).toBe(true);
|
||||
|
||||
// Confirm password doesn't match the new password
|
||||
await changePassword.setNewPassword(credentials.password);
|
||||
await changePassword.setConfirmPassword(credentials.password + '2');
|
||||
expect(await changePassword.confirmPasswordError()).toBe(true);
|
||||
// Confirm password doesn't match the new password
|
||||
await changePassword.setNewPassword(credentials.password);
|
||||
await changePassword.setConfirmPassword(credentials.password + '2');
|
||||
expect(await changePassword.confirmPasswordError()).toBe(true);
|
||||
|
||||
// valid password
|
||||
await changePassword.setCurrentPassword(credentials.password);
|
||||
await changePassword.setNewPassword(newPassword);
|
||||
await changePassword.setConfirmPassword(newPassword);
|
||||
expect(await changePassword.submitButton()).toBe(true);
|
||||
});
|
||||
// valid password
|
||||
await changePassword.setCurrentPassword(credentials.password);
|
||||
await changePassword.setNewPassword(newPassword);
|
||||
await changePassword.setConfirmPassword(newPassword);
|
||||
expect(await changePassword.submitButton()).toBe(true);
|
||||
});
|
||||
|
||||
test('change password with short password tooltip shows, cancel and try to change password again, tooltip is not shown', async ({
|
||||
pages: { settings, changePassword },
|
||||
}) => {
|
||||
// Short password
|
||||
await changePassword.setNewPassword('short');
|
||||
expect(await changePassword.passwordLengthError()).toBe(true);
|
||||
test('change password with short password tooltip shows, cancel and try to change password again, tooltip is not shown', async ({
|
||||
pages: { settings, changePassword },
|
||||
}) => {
|
||||
// Short password
|
||||
await changePassword.setNewPassword('short');
|
||||
expect(await changePassword.passwordLengthError()).toBe(true);
|
||||
|
||||
// Click cancel and navigate to change password again
|
||||
await changePassword.clickCancelChangePassword();
|
||||
await settings.password.clickChange();
|
||||
expect(await changePassword.validPasswordLength()).toBe(true);
|
||||
});
|
||||
// Click cancel and navigate to change password again
|
||||
await changePassword.clickCancelChangePassword();
|
||||
await settings.password.clickChange();
|
||||
expect(await changePassword.validPasswordLength()).toBe(true);
|
||||
});
|
||||
|
||||
test('reset password via settings works', async ({
|
||||
pages: { login, resetPassword },
|
||||
}, { project }) => {
|
||||
test.slow();
|
||||
test('reset password via settings works', async ({
|
||||
pages: { login, resetPassword },
|
||||
}, { project }) => {
|
||||
test.slow();
|
||||
|
||||
// Click forgot password link
|
||||
await login.clickForgotPassword();
|
||||
// Click forgot password link
|
||||
await login.clickForgotPassword();
|
||||
|
||||
// Verify it navigates to reset password page
|
||||
await resetPassword.resetPasswordHeader();
|
||||
// Verify it navigates to reset password page
|
||||
await resetPassword.resetPasswordHeader();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -1,4 +1,8 @@
|
|||
import { test, expect, newPages } from '../../lib/fixtures/standard';
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
import { test, expect } from '../../lib/fixtures/standard';
|
||||
|
||||
test.describe('severity-1 #smoke', () => {
|
||||
// https://testrail.stage.mozaws.net/index.php?/cases/view/1293493
|
||||
|
|
|
@ -1,4 +1,8 @@
|
|||
import { test, expect, newPages } from '../../lib/fixtures/standard';
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
import { test, expect } from '../../lib/fixtures/standard';
|
||||
|
||||
test.describe('severity-2 #smoke', () => {
|
||||
// https://testrail.stage.mozaws.net/index.php?/cases/view/1293371
|
||||
|
|
|
@ -1,4 +1,8 @@
|
|||
import { test, expect, newPages } from '../../lib/fixtures/standard';
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
import { test, expect } from '../../lib/fixtures/standard';
|
||||
|
||||
test.describe('severity-1 #smoke', () => {
|
||||
// https://testrail.stage.mozaws.net/index.php?/cases/view/1293407
|
||||
|
@ -53,7 +57,7 @@ test.describe('severity-1 #smoke', () => {
|
|||
});
|
||||
});
|
||||
|
||||
test.describe('severity-3 #smoke', () => {
|
||||
test.describe('severity-2 #smoke', () => {
|
||||
// https://testrail.stage.mozaws.net/index.php?/cases/view/1293501
|
||||
test('settings bento menu #1293501', async ({
|
||||
page,
|
||||
|
|
|
@ -1,3 +1,7 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
import { test, expect } from '../../lib/fixtures/standard';
|
||||
import { EmailHeader, EmailType } from '../../lib/email';
|
||||
|
||||
|
|
|
@ -1,3 +1,7 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
import { test, expect } from '../../lib/fixtures/standard';
|
||||
|
||||
test.describe('password visibility tests', () => {
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -1,156 +1,162 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
import { test, expect } from '../../lib/fixtures/standard';
|
||||
import { EmailHeader, EmailType } from '../../lib/email';
|
||||
|
||||
test.describe('two step auth', () => {
|
||||
test.beforeEach(async ({}, { project }) => {
|
||||
// 2FA test can be slow because of time to generate recovery keys
|
||||
test.slow();
|
||||
});
|
||||
test.describe('severity-1 #smoke', () => {
|
||||
test.describe('two step auth', () => {
|
||||
test.beforeEach(async ({}, { project }) => {
|
||||
// 2FA test can be slow because of time to generate recovery keys
|
||||
test.slow();
|
||||
});
|
||||
|
||||
// https://testrail.stage.mozaws.net/index.php?/cases/view/1293446
|
||||
// https://testrail.stage.mozaws.net/index.php?/cases/view/1293452
|
||||
test('add and remove totp', async ({
|
||||
credentials,
|
||||
pages: { settings, totp, login },
|
||||
}) => {
|
||||
await settings.goto();
|
||||
let status = await settings.totp.statusText();
|
||||
expect(status).toEqual('Not Set');
|
||||
await settings.totp.clickAdd();
|
||||
await totp.enable(credentials);
|
||||
await settings.waitForAlertBar();
|
||||
status = await settings.totp.statusText();
|
||||
expect(status).toEqual('Enabled');
|
||||
await settings.totp.clickDisable();
|
||||
await settings.clickModalConfirm();
|
||||
await settings.waitForAlertBar();
|
||||
status = await settings.totp.statusText();
|
||||
expect(status).toEqual('Not Set');
|
||||
// https://testrail.stage.mozaws.net/index.php?/cases/view/1293446
|
||||
// https://testrail.stage.mozaws.net/index.php?/cases/view/1293452
|
||||
test('add and remove totp', async ({
|
||||
credentials,
|
||||
pages: { settings, totp, login },
|
||||
}) => {
|
||||
await settings.goto();
|
||||
let status = await settings.totp.statusText();
|
||||
expect(status).toEqual('Not Set');
|
||||
await settings.totp.clickAdd();
|
||||
await totp.enable(credentials);
|
||||
await settings.waitForAlertBar();
|
||||
status = await settings.totp.statusText();
|
||||
expect(status).toEqual('Enabled');
|
||||
await settings.totp.clickDisable();
|
||||
await settings.clickModalConfirm();
|
||||
await settings.waitForAlertBar();
|
||||
status = await settings.totp.statusText();
|
||||
expect(status).toEqual('Not Set');
|
||||
|
||||
// Login to verify no prompt for code
|
||||
await settings.signOut();
|
||||
await login.login(credentials.email, credentials.password);
|
||||
expect(await login.isUserLoggedIn()).toBe(true);
|
||||
});
|
||||
// Login to verify no prompt for code
|
||||
await settings.signOut();
|
||||
await login.login(credentials.email, credentials.password);
|
||||
expect(await login.isUserLoggedIn()).toBe(true);
|
||||
});
|
||||
|
||||
// https://testrail.stage.mozaws.net/index.php?/cases/view/1293445
|
||||
test('totp use QR code #1293445', async ({
|
||||
credentials,
|
||||
pages: { settings, totp },
|
||||
}) => {
|
||||
await settings.goto();
|
||||
let status = await settings.totp.statusText();
|
||||
expect(status).toEqual('Not Set');
|
||||
await settings.totp.clickAdd();
|
||||
await totp.enable(credentials, 'qr');
|
||||
await settings.waitForAlertBar();
|
||||
status = await settings.totp.statusText();
|
||||
expect(status).toEqual('Enabled');
|
||||
});
|
||||
// https://testrail.stage.mozaws.net/index.php?/cases/view/1293445
|
||||
test('totp use QR code #1293445', async ({
|
||||
credentials,
|
||||
pages: { settings, totp },
|
||||
}) => {
|
||||
await settings.goto();
|
||||
let status = await settings.totp.statusText();
|
||||
expect(status).toEqual('Not Set');
|
||||
await settings.totp.clickAdd();
|
||||
await totp.enable(credentials, 'qr');
|
||||
await settings.waitForAlertBar();
|
||||
status = await settings.totp.statusText();
|
||||
expect(status).toEqual('Enabled');
|
||||
});
|
||||
|
||||
// https://testrail.stage.mozaws.net/index.php?/cases/view/1293459
|
||||
test('add TOTP and login', async ({
|
||||
credentials,
|
||||
pages: { login, settings, totp },
|
||||
}) => {
|
||||
await settings.goto();
|
||||
await settings.totp.clickAdd();
|
||||
await totp.enable(credentials);
|
||||
await settings.signOut();
|
||||
await login.login(credentials.email, credentials.password);
|
||||
await login.setTotp(credentials.secret);
|
||||
const status = await settings.totp.statusText();
|
||||
expect(status).toEqual('Enabled');
|
||||
});
|
||||
// https://testrail.stage.mozaws.net/index.php?/cases/view/1293459
|
||||
test('add TOTP and login', async ({
|
||||
credentials,
|
||||
pages: { login, settings, totp },
|
||||
}) => {
|
||||
await settings.goto();
|
||||
await settings.totp.clickAdd();
|
||||
await totp.enable(credentials);
|
||||
await settings.signOut();
|
||||
await login.login(credentials.email, credentials.password);
|
||||
await login.setTotp(credentials.secret);
|
||||
const status = await settings.totp.statusText();
|
||||
expect(status).toEqual('Enabled');
|
||||
});
|
||||
|
||||
// https://testrail.stage.mozaws.net/index.php?/cases/view/1293450
|
||||
test('can change backup authentication codes #1293450', async ({
|
||||
credentials,
|
||||
page,
|
||||
pages: { settings, totp, login },
|
||||
}) => {
|
||||
await settings.goto();
|
||||
await settings.totp.clickAdd();
|
||||
const { recoveryCodes } = await totp.enable(credentials);
|
||||
await settings.totp.clickChange();
|
||||
await settings.clickModalConfirm();
|
||||
const newCodes = await totp.getRecoveryCodes();
|
||||
for (const code of recoveryCodes) {
|
||||
expect(newCodes).not.toContain(code);
|
||||
}
|
||||
await settings.clickRecoveryCodeAck();
|
||||
await totp.setRecoveryCode(newCodes[0]);
|
||||
await totp.submit();
|
||||
await settings.waitForAlertBar();
|
||||
await settings.signOut();
|
||||
await login.login(credentials.email, credentials.password);
|
||||
// https://testrail.stage.mozaws.net/index.php?/cases/view/1293450
|
||||
test('can change backup authentication codes #1293450', async ({
|
||||
credentials,
|
||||
page,
|
||||
pages: { settings, totp, login },
|
||||
}) => {
|
||||
await settings.goto();
|
||||
await settings.totp.clickAdd();
|
||||
const { recoveryCodes } = await totp.enable(credentials);
|
||||
await settings.totp.clickChange();
|
||||
await settings.clickModalConfirm();
|
||||
const newCodes = await totp.getRecoveryCodes();
|
||||
for (const code of recoveryCodes) {
|
||||
expect(newCodes).not.toContain(code);
|
||||
}
|
||||
await settings.clickRecoveryCodeAck();
|
||||
await totp.setRecoveryCode(newCodes[0]);
|
||||
await totp.submit();
|
||||
await settings.waitForAlertBar();
|
||||
await settings.signOut();
|
||||
await login.login(credentials.email, credentials.password);
|
||||
|
||||
// Make sure an invalid code doesn't work
|
||||
await login.clickUseRecoveryCode();
|
||||
await login.setCode('invalid!!!!');
|
||||
await login.submitButton.click();
|
||||
await expect(login.tooltip).toContainText('Invalid');
|
||||
// Make sure an invalid code doesn't work
|
||||
await login.clickUseRecoveryCode();
|
||||
await login.setCode('invalid!!!!');
|
||||
await login.submitButton.click();
|
||||
await expect(login.tooltip).toContainText('Invalid');
|
||||
|
||||
// Apply the correct code
|
||||
await login.setCode(newCodes[0]);
|
||||
await login.submit();
|
||||
// Apply the correct code
|
||||
await login.setCode(newCodes[0]);
|
||||
await login.submit();
|
||||
|
||||
expect(page.url()).toContain(settings.url);
|
||||
});
|
||||
expect(page.url()).toContain(settings.url);
|
||||
});
|
||||
|
||||
// https://testrail.stage.mozaws.net/index.php?/cases/view/1293460
|
||||
test('can get new backup authentication codes via email #1293460', async ({
|
||||
target,
|
||||
credentials,
|
||||
pages: { page, login, settings, totp },
|
||||
}, { project }) => {
|
||||
await settings.goto();
|
||||
await settings.totp.clickAdd();
|
||||
const { recoveryCodes } = await totp.enable(credentials);
|
||||
await settings.signOut();
|
||||
for (let i = 0; i < recoveryCodes.length - 3; i++) {
|
||||
// https://testrail.stage.mozaws.net/index.php?/cases/view/1293460
|
||||
test('can get new backup authentication codes via email #1293460', async ({
|
||||
target,
|
||||
credentials,
|
||||
pages: { page, login, settings, totp },
|
||||
}, { project }) => {
|
||||
await settings.goto();
|
||||
await settings.totp.clickAdd();
|
||||
const { recoveryCodes } = await totp.enable(credentials);
|
||||
await settings.signOut();
|
||||
for (let i = 0; i < recoveryCodes.length - 3; i++) {
|
||||
await login.login(
|
||||
credentials.email,
|
||||
credentials.password,
|
||||
recoveryCodes[i]
|
||||
);
|
||||
await login.page.waitForURL(/settings/);
|
||||
await settings.signOut();
|
||||
}
|
||||
await login.login(
|
||||
credentials.email,
|
||||
credentials.password,
|
||||
recoveryCodes[i]
|
||||
recoveryCodes[recoveryCodes.length - 1]
|
||||
);
|
||||
await login.page.waitForURL(/settings/);
|
||||
await settings.signOut();
|
||||
}
|
||||
await login.login(
|
||||
credentials.email,
|
||||
credentials.password,
|
||||
recoveryCodes[recoveryCodes.length - 1]
|
||||
);
|
||||
await login.page.waitForURL(/settings/);
|
||||
const link = await target.email.waitForEmail(
|
||||
credentials.email,
|
||||
EmailType.lowRecoveryCodes,
|
||||
EmailHeader.link
|
||||
);
|
||||
await page.goto(link);
|
||||
const newCodes = await totp.getRecoveryCodes();
|
||||
expect(newCodes.length).toEqual(recoveryCodes.length);
|
||||
});
|
||||
const link = await target.email.waitForEmail(
|
||||
credentials.email,
|
||||
EmailType.lowRecoveryCodes,
|
||||
EmailHeader.link
|
||||
);
|
||||
await page.goto(link);
|
||||
const newCodes = await totp.getRecoveryCodes();
|
||||
expect(newCodes.length).toEqual(recoveryCodes.length);
|
||||
});
|
||||
|
||||
// https://testrail.stage.mozaws.net/index.php?/cases/view/1293461
|
||||
test('delete account with totp enabled #1293461', async ({
|
||||
credentials,
|
||||
page,
|
||||
pages: { settings, totp, login, deleteAccount },
|
||||
}) => {
|
||||
await settings.goto();
|
||||
await settings.totp.clickAdd();
|
||||
const { secret } = await totp.enable(credentials);
|
||||
await settings.signOut();
|
||||
await login.login(credentials.email, credentials.password);
|
||||
await login.setTotp(secret);
|
||||
await settings.clickDeleteAccount();
|
||||
await deleteAccount.checkAllBoxes();
|
||||
await deleteAccount.clickContinue();
|
||||
await deleteAccount.setPassword(credentials.password);
|
||||
await deleteAccount.submit();
|
||||
const success = await page.waitForSelector('.success');
|
||||
expect(await success.isVisible()).toBeTruthy();
|
||||
// https://testrail.stage.mozaws.net/index.php?/cases/view/1293461
|
||||
test('delete account with totp enabled #1293461', async ({
|
||||
credentials,
|
||||
page,
|
||||
pages: { settings, totp, login, deleteAccount },
|
||||
}) => {
|
||||
await settings.goto();
|
||||
await settings.totp.clickAdd();
|
||||
const { secret } = await totp.enable(credentials);
|
||||
await settings.signOut();
|
||||
await login.login(credentials.email, credentials.password);
|
||||
await login.setTotp(secret);
|
||||
await settings.clickDeleteAccount();
|
||||
await deleteAccount.checkAllBoxes();
|
||||
await deleteAccount.clickContinue();
|
||||
await deleteAccount.setPassword(credentials.password);
|
||||
await deleteAccount.submit();
|
||||
const success = await page.waitForSelector('.success');
|
||||
expect(await success.isVisible()).toBeTruthy();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -6,191 +6,203 @@ import { test, expect } from '../../lib/fixtures/standard';
|
|||
|
||||
const password = 'password12345678';
|
||||
|
||||
test.describe('signup here', () => {
|
||||
test.beforeEach(async () => {
|
||||
test.slow();
|
||||
});
|
||||
test.describe('severity-2 #smoke', () => {
|
||||
test.describe('signup here', () => {
|
||||
test.beforeEach(async () => {
|
||||
test.slow();
|
||||
});
|
||||
|
||||
test('with an invalid email, empty email query query param', async ({
|
||||
target,
|
||||
page,
|
||||
pages: { login },
|
||||
}) => {
|
||||
await page.goto(`${target.contentServerUrl}?email=invalid`);
|
||||
expect(await login.getErrorMessage()).toContain('Invalid parameter: email');
|
||||
test('with an invalid email, empty email query query param', async ({
|
||||
target,
|
||||
page,
|
||||
pages: { login },
|
||||
}) => {
|
||||
await page.goto(`${target.contentServerUrl}?email=invalid`);
|
||||
expect(await login.getErrorMessage()).toContain(
|
||||
'Invalid parameter: email'
|
||||
);
|
||||
|
||||
await page.goto(`${target.contentServerUrl}?email=`);
|
||||
expect(await login.getErrorMessage()).toContain('Invalid parameter: email');
|
||||
});
|
||||
|
||||
test('signup with email with leading/trailing whitespace on the email', async ({
|
||||
target,
|
||||
page,
|
||||
pages: { login },
|
||||
}) => {
|
||||
let email = login.createEmail();
|
||||
let emailWithoutSpace = email;
|
||||
let emailWithSpace = ' ' + email;
|
||||
await page.goto(target.contentServerUrl);
|
||||
await login.fillOutFirstSignUp(emailWithSpace, password, { verify: false });
|
||||
|
||||
// Verify the confirm code header and the email
|
||||
await login.waitForSignUpCodeHeader();
|
||||
expect(await login.confirmEmail()).toContain(emailWithoutSpace);
|
||||
|
||||
// Need to clear the cache to get the new email
|
||||
await login.clearCache();
|
||||
|
||||
await page.goto(target.contentServerUrl);
|
||||
email = login.createEmail();
|
||||
emailWithoutSpace = email;
|
||||
emailWithSpace = email + ' ';
|
||||
await login.fillOutFirstSignUp(emailWithSpace, password, { verify: false });
|
||||
await login.waitForSignUpCodeHeader();
|
||||
expect(await login.confirmEmail()).toContain(emailWithoutSpace);
|
||||
});
|
||||
|
||||
test('signup with invalid email address', async ({
|
||||
target,
|
||||
page,
|
||||
pages: { login },
|
||||
}) => {
|
||||
await page.goto(target.contentServerUrl);
|
||||
await login.setEmail('invalidemail');
|
||||
await login.clickSubmit();
|
||||
|
||||
// Verify the error
|
||||
expect(await login.getTooltipError()).toContain('Valid email required');
|
||||
});
|
||||
|
||||
test('coppa is empty and too young', async ({
|
||||
target,
|
||||
page,
|
||||
pages: { login },
|
||||
}) => {
|
||||
const email = login.createEmail();
|
||||
await page.goto(target.contentServerUrl);
|
||||
await login.setEmail(email);
|
||||
await login.clickSubmit();
|
||||
await page.waitForURL(/signup/);
|
||||
await login.setPassword(password);
|
||||
await login.confirmPassword(password);
|
||||
await login.clickSubmit();
|
||||
|
||||
// Verify the error
|
||||
expect(await login.getTooltipError()).toContain(
|
||||
'You must enter your age to sign up'
|
||||
);
|
||||
|
||||
await login.setAge('12');
|
||||
await login.clickSubmit();
|
||||
|
||||
// Verify navigated to the cannot create account page
|
||||
await page.waitForURL(/cannot_create_account/);
|
||||
// TODO: this is flaky
|
||||
// expect(await login.cannotCreateAccountHeader()).toBe(true);
|
||||
});
|
||||
|
||||
test('sign up with non matching passwords', async ({
|
||||
target,
|
||||
page,
|
||||
pages: { login },
|
||||
}) => {
|
||||
const email = login.createEmail();
|
||||
await page.goto(target.contentServerUrl);
|
||||
await login.setEmail(email);
|
||||
await login.clickSubmit();
|
||||
await login.setPassword(password);
|
||||
await login.confirmPassword('wrongpassword');
|
||||
await login.setAge('24');
|
||||
await login.clickSubmit();
|
||||
|
||||
// Verify the error
|
||||
expect(await login.getTooltipError()).toContain('Passwords do not match');
|
||||
});
|
||||
|
||||
test('form prefill information is cleared after signup->sign out', async ({
|
||||
target,
|
||||
page,
|
||||
pages: { login, settings },
|
||||
}) => {
|
||||
const email = login.createEmail();
|
||||
await page.goto(target.contentServerUrl);
|
||||
await login.fillOutFirstSignUp(email, password);
|
||||
|
||||
// The original tab should transition to the settings page w/ success
|
||||
// message.
|
||||
expect(await login.isUserLoggedIn()).toBe(true);
|
||||
await settings.signOut();
|
||||
|
||||
// check the email address was cleared
|
||||
await login.waitForEmailHeader();
|
||||
expect(await login.getEmailInput()).toContain('');
|
||||
|
||||
await login.setEmail(login.createEmail());
|
||||
await login.clickSubmit();
|
||||
|
||||
// check the password was cleared
|
||||
expect(await login.getPasswordInput()).toContain('');
|
||||
});
|
||||
|
||||
test('signup via relier page and redirect after confirm', async ({
|
||||
pages: { login, relier },
|
||||
}) => {
|
||||
const email = login.createEmail();
|
||||
await relier.goto();
|
||||
await relier.clickEmailFirst();
|
||||
await login.fillOutFirstSignUp(email, password);
|
||||
expect(await relier.isLoggedIn()).toBe(true);
|
||||
});
|
||||
|
||||
test('signup, verify and sign out of two accounts, all in the same tab, then sign in to the first account', async ({
|
||||
target,
|
||||
page,
|
||||
pages: { login, settings },
|
||||
}) => {
|
||||
const email = login.createEmail();
|
||||
const secondEmail = login.createEmail();
|
||||
await page.goto(target.contentServerUrl);
|
||||
await login.fillOutFirstSignUp(email, password);
|
||||
|
||||
// The original tab should transition to the settings page w/ success
|
||||
// message.
|
||||
expect(await login.isUserLoggedIn()).toBe(true);
|
||||
|
||||
// Verify the account is in local storage and has a correct state
|
||||
const currentAccountUid = await page.evaluate(() => {
|
||||
return JSON.parse(
|
||||
localStorage.getItem('__fxa_storage.currentAccountUid') || ''
|
||||
await page.goto(`${target.contentServerUrl}?email=`);
|
||||
expect(await login.getErrorMessage()).toContain(
|
||||
'Invalid parameter: email'
|
||||
);
|
||||
});
|
||||
const accounts = await page.evaluate(() => {
|
||||
return JSON.parse(localStorage.getItem('__fxa_storage.accounts') || '{}');
|
||||
|
||||
test('signup with email with leading/trailing whitespace on the email', async ({
|
||||
target,
|
||||
page,
|
||||
pages: { login },
|
||||
}) => {
|
||||
let email = login.createEmail();
|
||||
let emailWithoutSpace = email;
|
||||
let emailWithSpace = ' ' + email;
|
||||
await page.goto(target.contentServerUrl);
|
||||
await login.fillOutFirstSignUp(emailWithSpace, password, {
|
||||
verify: false,
|
||||
});
|
||||
|
||||
// Verify the confirm code header and the email
|
||||
await login.waitForSignUpCodeHeader();
|
||||
expect(await login.confirmEmail()).toContain(emailWithoutSpace);
|
||||
|
||||
// Need to clear the cache to get the new email
|
||||
await login.clearCache();
|
||||
|
||||
await page.goto(target.contentServerUrl);
|
||||
email = login.createEmail();
|
||||
emailWithoutSpace = email;
|
||||
emailWithSpace = email + ' ';
|
||||
await login.fillOutFirstSignUp(emailWithSpace, password, {
|
||||
verify: false,
|
||||
});
|
||||
await login.waitForSignUpCodeHeader();
|
||||
expect(await login.confirmEmail()).toContain(emailWithoutSpace);
|
||||
});
|
||||
const account = accounts[currentAccountUid];
|
||||
expect(currentAccountUid).toBeDefined();
|
||||
expect(accounts).toBeDefined();
|
||||
expect(accounts[currentAccountUid]).toBeDefined();
|
||||
expect(account.email).toBe(email);
|
||||
expect(account.lastLogin).toBeDefined();
|
||||
expect(account.metricsEnabled).toBe(true);
|
||||
expect(account.sessionToken).toBeDefined();
|
||||
expect(account.uid).toBeDefined();
|
||||
expect(account.verified).toBe(true);
|
||||
|
||||
await settings.signOut();
|
||||
test('signup with invalid email address', async ({
|
||||
target,
|
||||
page,
|
||||
pages: { login },
|
||||
}) => {
|
||||
await page.goto(target.contentServerUrl);
|
||||
await login.setEmail('invalidemail');
|
||||
await login.clickSubmit();
|
||||
|
||||
await login.fillOutFirstSignUp(secondEmail, password);
|
||||
// Verify the error
|
||||
expect(await login.getTooltipError()).toContain('Valid email required');
|
||||
});
|
||||
|
||||
// The original tab should transition to the settings page w/ success
|
||||
// message.
|
||||
expect(await login.isUserLoggedIn()).toBe(true);
|
||||
await settings.signOut();
|
||||
test('coppa is empty and too young', async ({
|
||||
target,
|
||||
page,
|
||||
pages: { login },
|
||||
}) => {
|
||||
const email = login.createEmail();
|
||||
await page.goto(target.contentServerUrl);
|
||||
await login.setEmail(email);
|
||||
await login.clickSubmit();
|
||||
await page.waitForURL(/signup/);
|
||||
await login.setPassword(password);
|
||||
await login.confirmPassword(password);
|
||||
await login.clickSubmit();
|
||||
|
||||
await login.setEmail(email);
|
||||
await login.clickSubmit();
|
||||
await login.setPassword(password);
|
||||
await login.submit();
|
||||
expect(await login.isUserLoggedIn()).toBe(true);
|
||||
// Verify the error
|
||||
expect(await login.getTooltipError()).toContain(
|
||||
'You must enter your age to sign up'
|
||||
);
|
||||
|
||||
await login.setAge('12');
|
||||
await login.clickSubmit();
|
||||
|
||||
// Verify navigated to the cannot create account page
|
||||
await page.waitForURL(/cannot_create_account/);
|
||||
// TODO: this is flaky
|
||||
// expect(await login.cannotCreateAccountHeader()).toBe(true);
|
||||
});
|
||||
|
||||
test('sign up with non matching passwords', async ({
|
||||
target,
|
||||
page,
|
||||
pages: { login },
|
||||
}) => {
|
||||
const email = login.createEmail();
|
||||
await page.goto(target.contentServerUrl);
|
||||
await login.setEmail(email);
|
||||
await login.clickSubmit();
|
||||
await login.setPassword(password);
|
||||
await login.confirmPassword('wrongpassword');
|
||||
await login.setAge('24');
|
||||
await login.clickSubmit();
|
||||
|
||||
// Verify the error
|
||||
expect(await login.getTooltipError()).toContain('Passwords do not match');
|
||||
});
|
||||
|
||||
test('form prefill information is cleared after signup->sign out', async ({
|
||||
target,
|
||||
page,
|
||||
pages: { login, settings },
|
||||
}) => {
|
||||
const email = login.createEmail();
|
||||
await page.goto(target.contentServerUrl);
|
||||
await login.fillOutFirstSignUp(email, password);
|
||||
|
||||
// The original tab should transition to the settings page w/ success
|
||||
// message.
|
||||
expect(await login.isUserLoggedIn()).toBe(true);
|
||||
await settings.signOut();
|
||||
|
||||
// check the email address was cleared
|
||||
await login.waitForEmailHeader();
|
||||
expect(await login.getEmailInput()).toContain('');
|
||||
|
||||
await login.setEmail(login.createEmail());
|
||||
await login.clickSubmit();
|
||||
|
||||
// check the password was cleared
|
||||
expect(await login.getPasswordInput()).toContain('');
|
||||
});
|
||||
|
||||
test('signup via relier page and redirect after confirm', async ({
|
||||
pages: { login, relier },
|
||||
}) => {
|
||||
const email = login.createEmail();
|
||||
await relier.goto();
|
||||
await relier.clickEmailFirst();
|
||||
await login.fillOutFirstSignUp(email, password);
|
||||
expect(await relier.isLoggedIn()).toBe(true);
|
||||
});
|
||||
|
||||
test('signup, verify and sign out of two accounts, all in the same tab, then sign in to the first account', async ({
|
||||
target,
|
||||
page,
|
||||
pages: { login, settings },
|
||||
}) => {
|
||||
const email = login.createEmail();
|
||||
const secondEmail = login.createEmail();
|
||||
await page.goto(target.contentServerUrl);
|
||||
await login.fillOutFirstSignUp(email, password);
|
||||
|
||||
// The original tab should transition to the settings page w/ success
|
||||
// message.
|
||||
expect(await login.isUserLoggedIn()).toBe(true);
|
||||
|
||||
// Verify the account is in local storage and has a correct state
|
||||
const currentAccountUid = await page.evaluate(() => {
|
||||
return JSON.parse(
|
||||
localStorage.getItem('__fxa_storage.currentAccountUid') || ''
|
||||
);
|
||||
});
|
||||
const accounts = await page.evaluate(() => {
|
||||
return JSON.parse(
|
||||
localStorage.getItem('__fxa_storage.accounts') || '{}'
|
||||
);
|
||||
});
|
||||
const account = accounts[currentAccountUid];
|
||||
expect(currentAccountUid).toBeDefined();
|
||||
expect(accounts).toBeDefined();
|
||||
expect(accounts[currentAccountUid]).toBeDefined();
|
||||
expect(account.email).toBe(email);
|
||||
expect(account.lastLogin).toBeDefined();
|
||||
expect(account.metricsEnabled).toBe(true);
|
||||
expect(account.sessionToken).toBeDefined();
|
||||
expect(account.uid).toBeDefined();
|
||||
expect(account.verified).toBe(true);
|
||||
|
||||
await settings.signOut();
|
||||
|
||||
await login.fillOutFirstSignUp(secondEmail, password);
|
||||
|
||||
// The original tab should transition to the settings page w/ success
|
||||
// message.
|
||||
expect(await login.isUserLoggedIn()).toBe(true);
|
||||
await settings.signOut();
|
||||
|
||||
await login.setEmail(email);
|
||||
await login.clickSubmit();
|
||||
await login.setPassword(password);
|
||||
await login.submit();
|
||||
expect(await login.isUserLoggedIn()).toBe(true);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -7,50 +7,54 @@ import { test, expect } from '../../lib/fixtures/standard';
|
|||
const PASSWORD = 'passwordzxcv';
|
||||
let email;
|
||||
|
||||
test.describe('Sign up with code', () => {
|
||||
test.beforeEach(async ({ pages: { login } }) => {
|
||||
test.slow();
|
||||
email = login.createEmail();
|
||||
await login.clearCache();
|
||||
});
|
||||
|
||||
test('bounced email', async ({ target, page, pages: { login } }) => {
|
||||
const client = await login.getFxaClient(target);
|
||||
await page.goto(target.contentServerUrl, {
|
||||
waitUntil: 'load',
|
||||
test.describe('severity-1 #smoke', () => {
|
||||
test.describe('Sign up with code', () => {
|
||||
test.beforeEach(async ({ pages: { login } }) => {
|
||||
test.slow();
|
||||
email = login.createEmail();
|
||||
await login.clearCache();
|
||||
});
|
||||
await login.fillOutFirstSignUp(email, PASSWORD);
|
||||
|
||||
await client.accountDestroy(email, PASSWORD);
|
||||
await login.waitForPasswordHeader();
|
||||
});
|
||||
test('bounced email', async ({ target, page, pages: { login } }) => {
|
||||
const client = await login.getFxaClient(target);
|
||||
await page.goto(target.contentServerUrl, {
|
||||
waitUntil: 'load',
|
||||
});
|
||||
await login.fillOutFirstSignUp(email, PASSWORD);
|
||||
|
||||
test('valid code then click back', async ({
|
||||
target,
|
||||
page,
|
||||
pages: { login },
|
||||
}) => {
|
||||
await page.goto(target.contentServerUrl, {
|
||||
waitUntil: 'load',
|
||||
await client.accountDestroy(email, PASSWORD);
|
||||
await login.waitForPasswordHeader();
|
||||
});
|
||||
await login.fillOutFirstSignUp(email, PASSWORD, {waitForNavOnSubmit: false});
|
||||
await page.goBack({waitUntil: 'load'});
|
||||
expect(await login.isUserLoggedIn()).toBe(true);
|
||||
});
|
||||
|
||||
test('invalid code', async ({
|
||||
target,
|
||||
page,
|
||||
pages: { login, signinTokenCode },
|
||||
}) => {
|
||||
await page.goto(target.contentServerUrl, {
|
||||
waitUntil: 'load',
|
||||
test('valid code then click back', async ({
|
||||
target,
|
||||
page,
|
||||
pages: { login },
|
||||
}) => {
|
||||
await page.goto(target.contentServerUrl, {
|
||||
waitUntil: 'load',
|
||||
});
|
||||
await login.fillOutFirstSignUp(email, PASSWORD, {
|
||||
waitForNavOnSubmit: false,
|
||||
});
|
||||
await page.goBack({ waitUntil: 'load' });
|
||||
expect(await login.isUserLoggedIn()).toBe(true);
|
||||
});
|
||||
|
||||
test('invalid code', async ({
|
||||
target,
|
||||
page,
|
||||
pages: { login, signinTokenCode },
|
||||
}) => {
|
||||
await page.goto(target.contentServerUrl, {
|
||||
waitUntil: 'load',
|
||||
});
|
||||
await login.fillOutFirstSignUp(email, PASSWORD, { verify: false });
|
||||
await login.setCode('1234');
|
||||
await signinTokenCode.clickSubmitButton();
|
||||
expect(await login.getTooltipError()).toContain(
|
||||
'Invalid or expired confirmation code'
|
||||
);
|
||||
});
|
||||
await login.fillOutFirstSignUp(email, PASSWORD, { verify: false });
|
||||
await login.setCode('1234');
|
||||
await signinTokenCode.clickSubmitButton();
|
||||
expect(await login.getTooltipError()).toContain(
|
||||
'Invalid or expired confirmation code'
|
||||
);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -1,27 +1,33 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
import { test, expect, newPagesForSync } from '../../lib/fixtures/standard';
|
||||
|
||||
test.describe('connect_another_device', () => {
|
||||
test('signup Fx Desktop, load /connect_another_device page', async ({
|
||||
credentials,
|
||||
target,
|
||||
}) => {
|
||||
const { browser, page, login, connectAnotherDevice } =
|
||||
await newPagesForSync(target);
|
||||
await target.auth.accountDestroy(credentials.email, credentials.password);
|
||||
test.describe('severity-2 #smoke', () => {
|
||||
test.describe('connect_another_device', () => {
|
||||
test('signup Fx Desktop, load /connect_another_device page', async ({
|
||||
credentials,
|
||||
target,
|
||||
}) => {
|
||||
const { browser, page, login, connectAnotherDevice } =
|
||||
await newPagesForSync(target);
|
||||
await target.auth.accountDestroy(credentials.email, credentials.password);
|
||||
|
||||
await page.goto(
|
||||
`${target.contentServerUrl}?context=fx_desktop_v3&service=sync&action=email`,
|
||||
{ waitUntil: 'load' }
|
||||
);
|
||||
await login.fillOutFirstSignUp(credentials.email, credentials.password);
|
||||
await page.goto(
|
||||
`${target.contentServerUrl}?context=fx_desktop_v3&service=sync&action=email`,
|
||||
{ waitUntil: 'load' }
|
||||
);
|
||||
await login.fillOutFirstSignUp(credentials.email, credentials.password);
|
||||
|
||||
// Move on to the connect another device page
|
||||
await connectAnotherDevice.goto('load');
|
||||
await expect(connectAnotherDevice.header).toHaveCount(1);
|
||||
await expect(connectAnotherDevice.signInButton).toHaveCount(0);
|
||||
await expect(connectAnotherDevice.installFxDesktop).toHaveCount(1);
|
||||
await expect(connectAnotherDevice.success).toHaveCount(0);
|
||||
// Move on to the connect another device page
|
||||
await connectAnotherDevice.goto('load');
|
||||
await expect(connectAnotherDevice.header).toHaveCount(1);
|
||||
await expect(connectAnotherDevice.signInButton).toHaveCount(0);
|
||||
await expect(connectAnotherDevice.installFxDesktop).toHaveCount(1);
|
||||
await expect(connectAnotherDevice.success).toHaveCount(0);
|
||||
|
||||
await browser?.close();
|
||||
await browser?.close();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -4,57 +4,59 @@
|
|||
|
||||
import { test, expect } from '../../lib/fixtures/standard';
|
||||
|
||||
test.describe('redirect_to', () => {
|
||||
test.beforeEach(async ({ credentials, pages: { settings, login } }) => {
|
||||
await settings.goto();
|
||||
await settings.signOut();
|
||||
await login.login(credentials.email, credentials.password);
|
||||
});
|
||||
test.describe('severity-2 #smoke', () => {
|
||||
test.describe('redirect_to', () => {
|
||||
test.beforeEach(async ({ credentials, pages: { settings, login } }) => {
|
||||
await settings.goto();
|
||||
await settings.signOut();
|
||||
await login.login(credentials.email, credentials.password);
|
||||
});
|
||||
|
||||
async function engageRedirect(page, target, redirectTo) {
|
||||
await page.goto(
|
||||
`${target.contentServerUrl}/confirm_signup_code?redirect_to=${redirectTo}`
|
||||
);
|
||||
await page.click('button[type=submit]');
|
||||
}
|
||||
async function engageRedirect(page, target, redirectTo) {
|
||||
await page.goto(
|
||||
`${target.contentServerUrl}/confirm_signup_code?redirect_to=${redirectTo}`
|
||||
);
|
||||
await page.click('button[type=submit]');
|
||||
}
|
||||
|
||||
test('prevent invalid redirect_to parameter', async ({
|
||||
target,
|
||||
pages: { page },
|
||||
}) => {
|
||||
const redirectTo = 'https://evil.com/';
|
||||
await engageRedirect(page, target, redirectTo);
|
||||
test('prevent invalid redirect_to parameter', async ({
|
||||
target,
|
||||
pages: { page },
|
||||
}) => {
|
||||
const redirectTo = 'https://evil.com/';
|
||||
await engageRedirect(page, target, redirectTo);
|
||||
|
||||
const error = await page.waitForSelector('.error');
|
||||
expect(await error.isVisible()).toBeTruthy();
|
||||
expect(await error.textContent()).toEqual('Invalid redirect!');
|
||||
expect(page.url).not.toEqual(redirectTo);
|
||||
});
|
||||
const error = await page.waitForSelector('.error');
|
||||
expect(await error.isVisible()).toBeTruthy();
|
||||
expect(await error.textContent()).toEqual('Invalid redirect!');
|
||||
expect(page.url).not.toEqual(redirectTo);
|
||||
});
|
||||
|
||||
test('prevent xss in redirect_to parameter', async ({
|
||||
target,
|
||||
pages: { page },
|
||||
}) => {
|
||||
const redirectTo = 'javascript:alert(1)';
|
||||
await engageRedirect(page, target, redirectTo);
|
||||
test('prevent xss in redirect_to parameter', async ({
|
||||
target,
|
||||
pages: { page },
|
||||
}) => {
|
||||
const redirectTo = 'javascript:alert(1)';
|
||||
await engageRedirect(page, target, redirectTo);
|
||||
|
||||
const error = await page.waitForSelector('.error');
|
||||
expect(await error.isVisible()).toBeTruthy();
|
||||
expect(await error.textContent()).toEqual('Invalid redirect!');
|
||||
});
|
||||
const error = await page.waitForSelector('.error');
|
||||
expect(await error.isVisible()).toBeTruthy();
|
||||
expect(await error.textContent()).toEqual('Invalid redirect!');
|
||||
});
|
||||
|
||||
test('allows valid redirect_to parameter', async ({
|
||||
target,
|
||||
pages: { page },
|
||||
}) => {
|
||||
const redirectTo = `${target.contentServerUrl}/settings`;
|
||||
await page.goto(
|
||||
`${target.contentServerUrl}/confirm_signup_code?redirect_to=${redirectTo}`
|
||||
);
|
||||
await page.click('button[type=submit]');
|
||||
test('allows valid redirect_to parameter', async ({
|
||||
target,
|
||||
pages: { page },
|
||||
}) => {
|
||||
const redirectTo = `${target.contentServerUrl}/settings`;
|
||||
await page.goto(
|
||||
`${target.contentServerUrl}/confirm_signup_code?redirect_to=${redirectTo}`
|
||||
);
|
||||
await page.click('button[type=submit]');
|
||||
|
||||
await page.waitForURL(/settings\?/);
|
||||
await page.waitForURL(/settings\?/);
|
||||
|
||||
expect(page.url().startsWith(redirectTo)).toBeTruthy();
|
||||
expect(page.url().startsWith(redirectTo)).toBeTruthy();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -1,3 +1,7 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
import { test, expect, newPagesForSync } from '../../lib/fixtures/standard';
|
||||
|
||||
test.describe('severity-1 #smoke', () => {
|
||||
|
@ -60,7 +64,7 @@ test.describe('severity-1 #smoke', () => {
|
|||
});
|
||||
});
|
||||
|
||||
test.describe('severity-3 #smoke', () => {
|
||||
test.describe('severity-2 #smoke', () => {
|
||||
// https://testrail.stage.mozaws.net/index.php?/cases/view/1293362
|
||||
// https://testrail.stage.mozaws.net/index.php?/cases/view/1293469
|
||||
test('can login to addons #1293362 #1293469', async ({
|
||||
|
|
|
@ -4,127 +4,129 @@
|
|||
|
||||
import { test, expect } from '../../lib/fixtures/standard';
|
||||
|
||||
test.describe('signin here', () => {
|
||||
test('signin verified with incorrect password, click `forgot password?`', async ({
|
||||
target,
|
||||
page,
|
||||
credentials,
|
||||
pages: { login, resetPassword },
|
||||
}) => {
|
||||
await page.goto(target.contentServerUrl);
|
||||
await login.setEmail(credentials.email);
|
||||
await login.clickSubmit();
|
||||
await login.setPassword('incorrect password');
|
||||
await login.clickSubmit();
|
||||
test.describe('severity-2 #smoke', () => {
|
||||
test.describe('signin here', () => {
|
||||
test('signin verified with incorrect password, click `forgot password?`', async ({
|
||||
target,
|
||||
page,
|
||||
credentials,
|
||||
pages: { login, resetPassword },
|
||||
}) => {
|
||||
await page.goto(target.contentServerUrl);
|
||||
await login.setEmail(credentials.email);
|
||||
await login.clickSubmit();
|
||||
await login.setPassword('incorrect password');
|
||||
await login.clickSubmit();
|
||||
|
||||
// Verify the error
|
||||
expect(await login.getTooltipError()).toContain('Incorrect password');
|
||||
// Verify the error
|
||||
expect(await login.getTooltipError()).toContain('Incorrect password');
|
||||
|
||||
//Click forgot password link
|
||||
await login.clickForgotPassword();
|
||||
//Click forgot password link
|
||||
await login.clickForgotPassword();
|
||||
|
||||
//Verify reset password header
|
||||
await resetPassword.resetPasswordHeader();
|
||||
});
|
||||
//Verify reset password header
|
||||
await resetPassword.resetPasswordHeader();
|
||||
});
|
||||
|
||||
test('signin with email with leading/trailing whitespace on the email', async ({
|
||||
target,
|
||||
page,
|
||||
credentials,
|
||||
pages: { login },
|
||||
}) => {
|
||||
const emailWithleadingSpace = ' ' + credentials.email;
|
||||
await page.goto(target.contentServerUrl);
|
||||
await login.fillOutEmailFirstSignIn(
|
||||
emailWithleadingSpace,
|
||||
credentials.password
|
||||
);
|
||||
test('signin with email with leading/trailing whitespace on the email', async ({
|
||||
target,
|
||||
page,
|
||||
credentials,
|
||||
pages: { login },
|
||||
}) => {
|
||||
const emailWithleadingSpace = ' ' + credentials.email;
|
||||
await page.goto(target.contentServerUrl);
|
||||
await login.fillOutEmailFirstSignIn(
|
||||
emailWithleadingSpace,
|
||||
credentials.password
|
||||
);
|
||||
|
||||
// Verify the header after login
|
||||
expect(await login.isUserLoggedIn()).toBe(true);
|
||||
// Verify the header after login
|
||||
expect(await login.isUserLoggedIn()).toBe(true);
|
||||
|
||||
// Need to clear the cache to get the new email
|
||||
await login.clearCache();
|
||||
// Need to clear the cache to get the new email
|
||||
await login.clearCache();
|
||||
|
||||
await page.goto(target.contentServerUrl);
|
||||
const emailWithTrailingSpace = credentials.email + ' ';
|
||||
await login.fillOutEmailFirstSignIn(
|
||||
emailWithTrailingSpace,
|
||||
credentials.password
|
||||
);
|
||||
await page.goto(target.contentServerUrl);
|
||||
const emailWithTrailingSpace = credentials.email + ' ';
|
||||
await login.fillOutEmailFirstSignIn(
|
||||
emailWithTrailingSpace,
|
||||
credentials.password
|
||||
);
|
||||
|
||||
// Verify the header after login
|
||||
expect(await login.isUserLoggedIn()).toBe(true);
|
||||
});
|
||||
// Verify the header after login
|
||||
expect(await login.isUserLoggedIn()).toBe(true);
|
||||
});
|
||||
|
||||
test('signin verified with password that incorrectly has leading whitespace', async ({
|
||||
target,
|
||||
page,
|
||||
credentials,
|
||||
pages: { login },
|
||||
}) => {
|
||||
await page.goto(target.contentServerUrl);
|
||||
await login.setEmail(credentials.email);
|
||||
await login.clickSubmit();
|
||||
await login.setPassword(' ' + credentials.password);
|
||||
await login.clickSubmit();
|
||||
test('signin verified with password that incorrectly has leading whitespace', async ({
|
||||
target,
|
||||
page,
|
||||
credentials,
|
||||
pages: { login },
|
||||
}) => {
|
||||
await page.goto(target.contentServerUrl);
|
||||
await login.setEmail(credentials.email);
|
||||
await login.clickSubmit();
|
||||
await login.setPassword(' ' + credentials.password);
|
||||
await login.clickSubmit();
|
||||
|
||||
// Verify the error
|
||||
expect(await login.getTooltipError()).toContain('Incorrect password');
|
||||
});
|
||||
// Verify the error
|
||||
expect(await login.getTooltipError()).toContain('Incorrect password');
|
||||
});
|
||||
|
||||
test('login as an existing user', async ({
|
||||
target,
|
||||
page,
|
||||
credentials,
|
||||
pages: { login, settings },
|
||||
}) => {
|
||||
await page.goto(target.contentServerUrl);
|
||||
await login.fillOutEmailFirstSignIn(
|
||||
credentials.email,
|
||||
credentials.password
|
||||
);
|
||||
test('login as an existing user', async ({
|
||||
target,
|
||||
page,
|
||||
credentials,
|
||||
pages: { login, settings },
|
||||
}) => {
|
||||
await page.goto(target.contentServerUrl);
|
||||
await login.fillOutEmailFirstSignIn(
|
||||
credentials.email,
|
||||
credentials.password
|
||||
);
|
||||
|
||||
// Verify the header after login
|
||||
expect(await login.isUserLoggedIn()).toBe(true);
|
||||
// Verify the header after login
|
||||
expect(await login.isUserLoggedIn()).toBe(true);
|
||||
|
||||
// Sign out
|
||||
await settings.signOut();
|
||||
// Sign out
|
||||
await settings.signOut();
|
||||
|
||||
// Login as existing user
|
||||
await login.setEmail(credentials.email);
|
||||
await login.clickSubmit();
|
||||
await login.setPassword(credentials.password);
|
||||
await login.clickSubmit();
|
||||
// Login as existing user
|
||||
await login.setEmail(credentials.email);
|
||||
await login.clickSubmit();
|
||||
await login.setPassword(credentials.password);
|
||||
await login.clickSubmit();
|
||||
|
||||
// Verify the header after login
|
||||
expect(await login.isUserLoggedIn()).toBe(true);
|
||||
});
|
||||
// Verify the header after login
|
||||
expect(await login.isUserLoggedIn()).toBe(true);
|
||||
});
|
||||
|
||||
test('with bounced email', async ({
|
||||
target,
|
||||
page,
|
||||
pages: { login, settings },
|
||||
}) => {
|
||||
const email = login.createEmail('sync{id}');
|
||||
const password = 'password123';
|
||||
await target.createAccount(email, password);
|
||||
await page.goto(
|
||||
`${target.contentServerUrl}?context=fx_desktop_v3&service=sync&action=email&`
|
||||
);
|
||||
await login.fillOutEmailFirstSignIn(email, password);
|
||||
test('with bounced email', async ({
|
||||
target,
|
||||
page,
|
||||
pages: { login, settings },
|
||||
}) => {
|
||||
const email = login.createEmail('sync{id}');
|
||||
const password = 'password123';
|
||||
await target.createAccount(email, password);
|
||||
await page.goto(
|
||||
`${target.contentServerUrl}?context=fx_desktop_v3&service=sync&action=email&`
|
||||
);
|
||||
await login.fillOutEmailFirstSignIn(email, password);
|
||||
|
||||
// Verify the header after login
|
||||
await login.waitForSignInCodeHeader();
|
||||
await target.auth.accountDestroy(email, password);
|
||||
await page.waitForURL(/signin_bounced/);
|
||||
// Verify the header after login
|
||||
await login.waitForSignInCodeHeader();
|
||||
await target.auth.accountDestroy(email, password);
|
||||
await page.waitForURL(/signin_bounced/);
|
||||
|
||||
//Verify sign in bounced header
|
||||
expect(await login.isSigninBouncedHeader()).toBe(true);
|
||||
await login.clickBouncedCreateAccount();
|
||||
//Verify sign in bounced header
|
||||
expect(await login.isSigninBouncedHeader()).toBe(true);
|
||||
await login.clickBouncedCreateAccount();
|
||||
|
||||
//Verify user redirected to login page
|
||||
await login.waitForEmailHeader();
|
||||
expect(await login.getEmailInput()).toContain('');
|
||||
//Verify user redirected to login page
|
||||
await login.waitForEmailHeader();
|
||||
expect(await login.getEmailInput()).toContain('');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -9,161 +9,171 @@ let email;
|
|||
let newEmail;
|
||||
let unverifiedEmail;
|
||||
|
||||
test.describe('signin blocked', () => {
|
||||
test.beforeEach(async ({ target, pages: { login } }) => {
|
||||
test.slow(); //This test has steps for email rendering that runs slow on stage
|
||||
blockedEmail = login.createEmail('blocked{id}');
|
||||
await target.auth.signUp(blockedEmail, password, {
|
||||
lang: 'en',
|
||||
preVerified: 'true',
|
||||
test.describe('severity-2 #smoke', () => {
|
||||
test.describe('signin blocked', () => {
|
||||
test.beforeEach(async ({ target, pages: { login } }) => {
|
||||
test.slow(); //This test has steps for email rendering that runs slow on stage
|
||||
blockedEmail = login.createEmail('blocked{id}');
|
||||
await target.auth.signUp(blockedEmail, password, {
|
||||
lang: 'en',
|
||||
preVerified: 'true',
|
||||
});
|
||||
email = await login.createEmail();
|
||||
await target.auth.signUp(email, password, {
|
||||
lang: 'en',
|
||||
preVerified: 'true',
|
||||
});
|
||||
newEmail = login.createEmail('blocked{id}');
|
||||
unverifiedEmail = login.createEmail('blocked{id}');
|
||||
await target.auth.signUp(unverifiedEmail, password, {
|
||||
lang: 'en',
|
||||
preVerified: 'false',
|
||||
});
|
||||
await login.clearCache();
|
||||
});
|
||||
email = await login.createEmail();
|
||||
await target.auth.signUp(email, password, {
|
||||
lang: 'en',
|
||||
preVerified: 'true',
|
||||
});
|
||||
newEmail = login.createEmail('blocked{id}');
|
||||
unverifiedEmail = login.createEmail('blocked{id}');
|
||||
await target.auth.signUp(unverifiedEmail, password, {
|
||||
lang: 'en',
|
||||
preVerified: 'false',
|
||||
});
|
||||
await login.clearCache();
|
||||
});
|
||||
|
||||
test.afterEach(async ({ target }) => {
|
||||
test.slow(); //The cleanup was timing out and exceeding 3000ms
|
||||
const emails = [blockedEmail, email, newEmail, unverifiedEmail];
|
||||
for (const email of emails) {
|
||||
if (email) {
|
||||
try {
|
||||
await target.auth.accountDestroy(email, password);
|
||||
} catch (e) {
|
||||
// Handle any errors if needed
|
||||
test.afterEach(async ({ target }) => {
|
||||
test.slow(); //The cleanup was timing out and exceeding 3000ms
|
||||
const emails = [blockedEmail, email, newEmail, unverifiedEmail];
|
||||
for (const email of emails) {
|
||||
if (email) {
|
||||
try {
|
||||
await target.auth.accountDestroy(email, password);
|
||||
} catch (e) {
|
||||
// Handle any errors if needed
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
test('valid code entered', async ({ target, page, pages: { login } }) => {
|
||||
await page.goto(target.contentServerUrl, {
|
||||
waitUntil: 'load',
|
||||
});
|
||||
await login.fillOutEmailFirstSignIn(blockedEmail, password);
|
||||
|
||||
//Verify sign in block header
|
||||
await login.waitForSigninUnblockHeader();
|
||||
expect(await login.getUnblockEmail()).toContain(blockedEmail);
|
||||
test('valid code entered', async ({ target, page, pages: { login } }) => {
|
||||
await page.goto(target.contentServerUrl, {
|
||||
waitUntil: 'load',
|
||||
});
|
||||
await login.fillOutEmailFirstSignIn(blockedEmail, password);
|
||||
|
||||
//Unblock the email
|
||||
await login.unblock(blockedEmail);
|
||||
//Verify sign in block header
|
||||
await login.waitForSigninUnblockHeader();
|
||||
expect(await login.getUnblockEmail()).toContain(blockedEmail);
|
||||
|
||||
//Verify logged in on Settings page
|
||||
expect(await login.isUserLoggedIn()).toBe(true);
|
||||
});
|
||||
//Unblock the email
|
||||
await login.unblock(blockedEmail);
|
||||
|
||||
test('incorrect code entered', async ({ target, page, pages: { login } }) => {
|
||||
await page.goto(target.contentServerUrl, {
|
||||
waitUntil: 'load',
|
||||
//Verify logged in on Settings page
|
||||
expect(await login.isUserLoggedIn()).toBe(true);
|
||||
});
|
||||
await login.fillOutEmailFirstSignIn(blockedEmail, password);
|
||||
|
||||
//Verify sign in block header
|
||||
await login.waitForSigninUnblockHeader();
|
||||
expect(await login.getUnblockEmail()).toContain(blockedEmail);
|
||||
await login.enterUnblockCode('incorrect');
|
||||
test('incorrect code entered', async ({
|
||||
target,
|
||||
page,
|
||||
pages: { login },
|
||||
}) => {
|
||||
await page.goto(target.contentServerUrl, {
|
||||
waitUntil: 'load',
|
||||
});
|
||||
await login.fillOutEmailFirstSignIn(blockedEmail, password);
|
||||
|
||||
//Verify tooltip error
|
||||
expect(await login.getTooltipError()).toContain(
|
||||
'Invalid authorization code'
|
||||
);
|
||||
//Verify sign in block header
|
||||
await login.waitForSigninUnblockHeader();
|
||||
expect(await login.getUnblockEmail()).toContain(blockedEmail);
|
||||
await login.enterUnblockCode('incorrect');
|
||||
|
||||
//Unblock the email
|
||||
await login.unblock(blockedEmail);
|
||||
//Verify tooltip error
|
||||
expect(await login.getTooltipError()).toContain(
|
||||
'Invalid authorization code'
|
||||
);
|
||||
|
||||
//Verify logged in on Settings page
|
||||
expect(await login.isUserLoggedIn()).toBe(true);
|
||||
});
|
||||
//Unblock the email
|
||||
await login.unblock(blockedEmail);
|
||||
|
||||
test('resend', async ({ target, page, pages: { login, resetPassword } }) => {
|
||||
await page.goto(target.contentServerUrl, {
|
||||
waitUntil: 'load',
|
||||
//Verify logged in on Settings page
|
||||
expect(await login.isUserLoggedIn()).toBe(true);
|
||||
});
|
||||
await login.fillOutEmailFirstSignIn(blockedEmail, password);
|
||||
|
||||
//Verify sign in block header
|
||||
await login.waitForSigninUnblockHeader();
|
||||
expect(await login.getUnblockEmail()).toContain(blockedEmail);
|
||||
test('resend', async ({
|
||||
target,
|
||||
page,
|
||||
pages: { login, resetPassword },
|
||||
}) => {
|
||||
await page.goto(target.contentServerUrl, {
|
||||
waitUntil: 'load',
|
||||
});
|
||||
await login.fillOutEmailFirstSignIn(blockedEmail, password);
|
||||
|
||||
//Click resend link
|
||||
await resetPassword.clickResend();
|
||||
//Verify sign in block header
|
||||
await login.waitForSigninUnblockHeader();
|
||||
expect(await login.getUnblockEmail()).toContain(blockedEmail);
|
||||
|
||||
//Verify success message
|
||||
expect(await resetPassword.resendSuccessMessage()).toContain(
|
||||
'Email resent. Add accounts@firefox.com to your contacts to ensure a smooth delivery.'
|
||||
);
|
||||
//Click resend link
|
||||
await resetPassword.clickResend();
|
||||
|
||||
//Unblock the email
|
||||
await login.unblock(blockedEmail);
|
||||
//Verify success message
|
||||
expect(await resetPassword.resendSuccessMessage()).toContain(
|
||||
'Email resent. Add accounts@firefox.com to your contacts to ensure a smooth delivery.'
|
||||
);
|
||||
|
||||
//Verify logged in on Settings page
|
||||
expect(await login.isUserLoggedIn()).toBe(true);
|
||||
});
|
||||
//Unblock the email
|
||||
await login.unblock(blockedEmail);
|
||||
|
||||
test('with primary email changed', async ({
|
||||
target,
|
||||
page,
|
||||
pages: { login, settings, secondaryEmail },
|
||||
}) => {
|
||||
await page.goto(target.contentServerUrl, {
|
||||
waitUntil: 'load',
|
||||
//Verify logged in on Settings page
|
||||
expect(await login.isUserLoggedIn()).toBe(true);
|
||||
});
|
||||
await login.fillOutEmailFirstSignIn(email, password);
|
||||
|
||||
//Verify logged in on Settings page
|
||||
expect(await login.isUserLoggedIn()).toBe(true);
|
||||
test('with primary email changed', async ({
|
||||
target,
|
||||
page,
|
||||
pages: { login, settings, secondaryEmail },
|
||||
}) => {
|
||||
await page.goto(target.contentServerUrl, {
|
||||
waitUntil: 'load',
|
||||
});
|
||||
await login.fillOutEmailFirstSignIn(email, password);
|
||||
|
||||
await settings.goto();
|
||||
await settings.secondaryEmail.clickAdd();
|
||||
await secondaryEmail.addAndVerify(newEmail);
|
||||
await settings.secondaryEmail.clickMakePrimary();
|
||||
await settings.signOut();
|
||||
//Verify logged in on Settings page
|
||||
expect(await login.isUserLoggedIn()).toBe(true);
|
||||
|
||||
await page.goto(target.contentServerUrl, {
|
||||
waitUntil: 'load',
|
||||
await settings.goto();
|
||||
await settings.secondaryEmail.clickAdd();
|
||||
await secondaryEmail.addAndVerify(newEmail);
|
||||
await settings.secondaryEmail.clickMakePrimary();
|
||||
await settings.signOut();
|
||||
|
||||
await page.goto(target.contentServerUrl, {
|
||||
waitUntil: 'load',
|
||||
});
|
||||
await login.fillOutEmailFirstSignIn(newEmail, password);
|
||||
|
||||
//Verify sign in block header
|
||||
await login.waitForSigninUnblockHeader();
|
||||
expect(await login.getUnblockEmail()).toContain(newEmail);
|
||||
|
||||
//Unblock the email
|
||||
await login.unblock(newEmail);
|
||||
|
||||
//Verify logged in on Settings page
|
||||
expect(await login.isUserLoggedIn()).toBe(true);
|
||||
});
|
||||
await login.fillOutEmailFirstSignIn(newEmail, password);
|
||||
|
||||
//Verify sign in block header
|
||||
await login.waitForSigninUnblockHeader();
|
||||
expect(await login.getUnblockEmail()).toContain(newEmail);
|
||||
test('unverified', async ({ target, page, pages: { login } }) => {
|
||||
await page.goto(target.contentServerUrl, {
|
||||
waitUntil: 'load',
|
||||
});
|
||||
await login.fillOutEmailFirstSignIn(unverifiedEmail, password);
|
||||
|
||||
//Unblock the email
|
||||
await login.unblock(newEmail);
|
||||
//Verify sign in block header
|
||||
await login.waitForSigninUnblockHeader();
|
||||
expect(await login.getUnblockEmail()).toContain(unverifiedEmail);
|
||||
|
||||
//Verify logged in on Settings page
|
||||
expect(await login.isUserLoggedIn()).toBe(true);
|
||||
});
|
||||
//Unblock the email
|
||||
await login.unblock(unverifiedEmail);
|
||||
|
||||
test('unverified', async ({ target, page, pages: { login } }) => {
|
||||
await page.goto(target.contentServerUrl, {
|
||||
waitUntil: 'load',
|
||||
//Verify confirm code header
|
||||
await login.waitForSignUpCodeHeader();
|
||||
|
||||
await login.fillOutSignInCode(unverifiedEmail);
|
||||
|
||||
//Verify logged in on Settings page
|
||||
expect(await login.isUserLoggedIn()).toBe(true);
|
||||
});
|
||||
await login.fillOutEmailFirstSignIn(unverifiedEmail, password);
|
||||
|
||||
//Verify sign in block header
|
||||
await login.waitForSigninUnblockHeader();
|
||||
expect(await login.getUnblockEmail()).toContain(unverifiedEmail);
|
||||
|
||||
//Unblock the email
|
||||
await login.unblock(unverifiedEmail);
|
||||
|
||||
//Verify confirm code header
|
||||
await login.waitForSignUpCodeHeader();
|
||||
|
||||
await login.fillOutSignInCode(unverifiedEmail);
|
||||
|
||||
//Verify logged in on Settings page
|
||||
expect(await login.isUserLoggedIn()).toBe(true);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -8,205 +8,207 @@ let email;
|
|||
let email2;
|
||||
let syncBrowserPages;
|
||||
|
||||
test.describe('signin cached', () => {
|
||||
test.beforeEach(async ({ target }) => {
|
||||
test.slow(); //This test has steps for email rendering that runs slow on stage
|
||||
syncBrowserPages = await newPagesForSync(target);
|
||||
const { login } = syncBrowserPages;
|
||||
email = login.createEmail('sync{id}');
|
||||
email2 = login.createEmail();
|
||||
await target.auth.signUp(email, password, {
|
||||
lang: 'en',
|
||||
preVerified: 'true',
|
||||
test.describe('severity-2 #smoke', () => {
|
||||
test.describe('signin cached', () => {
|
||||
test.beforeEach(async ({ target }) => {
|
||||
test.slow(); //This test has steps for email rendering that runs slow on stage
|
||||
syncBrowserPages = await newPagesForSync(target);
|
||||
const { login } = syncBrowserPages;
|
||||
email = login.createEmail('sync{id}');
|
||||
email2 = login.createEmail();
|
||||
await target.auth.signUp(email, password, {
|
||||
lang: 'en',
|
||||
preVerified: 'true',
|
||||
});
|
||||
await target.auth.signUp(email2, password, {
|
||||
lang: 'en',
|
||||
preVerified: 'true',
|
||||
});
|
||||
});
|
||||
await target.auth.signUp(email2, password, {
|
||||
lang: 'en',
|
||||
preVerified: 'true',
|
||||
});
|
||||
});
|
||||
|
||||
test.afterEach(async ({ target }) => {
|
||||
test.slow(); //The cleanup was timing out and exceeding 3000ms
|
||||
await syncBrowserPages.browser?.close();
|
||||
if (email) {
|
||||
// Cleanup any accounts created during the test
|
||||
try {
|
||||
await target.auth.accountDestroy(email, password);
|
||||
} catch (e) {
|
||||
// Handle the error here
|
||||
console.error('An error occurred during account cleanup:', e);
|
||||
// Optionally, rethrow the error to propagate it further
|
||||
throw e;
|
||||
test.afterEach(async ({ target }) => {
|
||||
test.slow(); //The cleanup was timing out and exceeding 3000ms
|
||||
await syncBrowserPages.browser?.close();
|
||||
if (email) {
|
||||
// Cleanup any accounts created during the test
|
||||
try {
|
||||
await target.auth.accountDestroy(email, password);
|
||||
} catch (e) {
|
||||
// Handle the error here
|
||||
console.error('An error occurred during account cleanup:', e);
|
||||
// Optionally, rethrow the error to propagate it further
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
test('sign in twice, on second attempt email will be cached', async ({
|
||||
target,
|
||||
}) => {
|
||||
const { page, login } = syncBrowserPages;
|
||||
await page.goto(target.contentServerUrl, {
|
||||
waitUntil: 'load',
|
||||
});
|
||||
await login.fillOutEmailFirstSignIn(email, password);
|
||||
|
||||
//Verify logged in on Settings page
|
||||
expect(await login.isUserLoggedIn()).toBe(true);
|
||||
|
||||
await login.clearSessionStorage();
|
||||
await page.goto(target.contentServerUrl, {
|
||||
waitUntil: 'load',
|
||||
});
|
||||
expect(await login.getPrefilledEmail()).toContain(email);
|
||||
await login.clickSignIn();
|
||||
|
||||
//Verify logged in on Settings page
|
||||
expect(await login.isUserLoggedIn()).toBe(true);
|
||||
});
|
||||
|
||||
test('sign in with incorrect email case before normalization fix, on second attempt canonical form is used', async ({
|
||||
target,
|
||||
}) => {
|
||||
const { page, login, settings } = syncBrowserPages;
|
||||
await page.goto(target.contentServerUrl, {
|
||||
waitUntil: 'load',
|
||||
});
|
||||
await login.fillOutEmailFirstSignIn(email, password);
|
||||
|
||||
//Verify logged in on Settings page
|
||||
expect(await login.isUserLoggedIn()).toBe(true);
|
||||
|
||||
await login.clearSessionStorage();
|
||||
await page.goto(target.contentServerUrl, {
|
||||
waitUntil: 'load',
|
||||
});
|
||||
await login.denormalizeStoredEmail(email);
|
||||
await page.reload();
|
||||
|
||||
expect(await login.getPrefilledEmail()).toContain(email);
|
||||
await login.clickSignIn();
|
||||
|
||||
//Verify logged in on Settings page
|
||||
expect(await login.isUserLoggedIn()).toBe(true);
|
||||
|
||||
//Verify email is normalized
|
||||
const primary = await settings.primaryEmail.statusText();
|
||||
expect(primary).toEqual(email);
|
||||
});
|
||||
|
||||
test('sign in once, use a different account', async ({ target }) => {
|
||||
const { page, login } = syncBrowserPages;
|
||||
await page.goto(target.contentServerUrl, {
|
||||
waitUntil: 'load',
|
||||
});
|
||||
await login.fillOutEmailFirstSignIn(email, password);
|
||||
|
||||
//Verify logged in on Settings page
|
||||
expect(await login.isUserLoggedIn()).toBe(true);
|
||||
await page.goto(target.contentServerUrl, {
|
||||
waitUntil: 'load',
|
||||
});
|
||||
//Check prefilled email
|
||||
expect(await login.getPrefilledEmail()).toContain(email);
|
||||
await login.useDifferentAccountLink();
|
||||
await login.fillOutEmailFirstSignIn(email2, password);
|
||||
|
||||
//Verify logged in on Settings page
|
||||
expect(await login.isUserLoggedIn()).toBe(true);
|
||||
|
||||
// testing to make sure cached signin comes back after a refresh
|
||||
await page.goto(target.contentServerUrl, {
|
||||
waitUntil: 'load',
|
||||
});
|
||||
//Check prefilled email
|
||||
expect(await login.getPrefilledEmail()).toContain(email2);
|
||||
});
|
||||
|
||||
test('expired cached credentials', async ({ target }) => {
|
||||
const { page, login } = syncBrowserPages;
|
||||
await page.goto(target.contentServerUrl, {
|
||||
waitUntil: 'load',
|
||||
});
|
||||
await login.fillOutEmailFirstSignIn(email, password);
|
||||
|
||||
//Verify logged in on Settings page
|
||||
expect(await login.isUserLoggedIn()).toBe(true);
|
||||
|
||||
await login.destroySession(email);
|
||||
await page.goto(target.contentServerUrl, {
|
||||
waitUntil: 'load',
|
||||
});
|
||||
|
||||
//Check prefilled email
|
||||
expect(await login.getPrefilledEmail()).toContain(email);
|
||||
await login.setPassword(password);
|
||||
await login.clickSubmit();
|
||||
test('sign in twice, on second attempt email will be cached', async ({
|
||||
target,
|
||||
}) => {
|
||||
const { page, login } = syncBrowserPages;
|
||||
await page.goto(target.contentServerUrl, {
|
||||
waitUntil: 'load',
|
||||
});
|
||||
await login.fillOutEmailFirstSignIn(email, password);
|
||||
|
||||
//Verify logged in on Settings page
|
||||
expect(await login.isUserLoggedIn()).toBe(true);
|
||||
});
|
||||
//Verify logged in on Settings page
|
||||
expect(await login.isUserLoggedIn()).toBe(true);
|
||||
|
||||
test('cached credentials that expire while on page', async ({ target }) => {
|
||||
const { page, login } = syncBrowserPages;
|
||||
await page.goto(target.contentServerUrl, {
|
||||
waitUntil: 'load',
|
||||
});
|
||||
await login.fillOutEmailFirstSignIn(email, password);
|
||||
await login.clearSessionStorage();
|
||||
await page.goto(target.contentServerUrl, {
|
||||
waitUntil: 'load',
|
||||
});
|
||||
expect(await login.getPrefilledEmail()).toContain(email);
|
||||
await login.clickSignIn();
|
||||
|
||||
//Verify logged in on Settings page
|
||||
expect(await login.isUserLoggedIn()).toBe(true);
|
||||
|
||||
await page.goto(target.contentServerUrl, {
|
||||
waitUntil: 'load',
|
||||
//Verify logged in on Settings page
|
||||
expect(await login.isUserLoggedIn()).toBe(true);
|
||||
});
|
||||
|
||||
//Check prefilled email
|
||||
expect(await login.getPrefilledEmail()).toContain(email);
|
||||
test('sign in with incorrect email case before normalization fix, on second attempt canonical form is used', async ({
|
||||
target,
|
||||
}) => {
|
||||
const { page, login, settings } = syncBrowserPages;
|
||||
await page.goto(target.contentServerUrl, {
|
||||
waitUntil: 'load',
|
||||
});
|
||||
await login.fillOutEmailFirstSignIn(email, password);
|
||||
|
||||
await login.destroySession(email);
|
||||
await login.clickSignIn();
|
||||
//Verify logged in on Settings page
|
||||
expect(await login.isUserLoggedIn()).toBe(true);
|
||||
|
||||
//Session expired error should show.
|
||||
expect(await login.signInError()).toContain(
|
||||
'Session expired. Sign in to continue.'
|
||||
);
|
||||
await login.setPassword(password);
|
||||
await login.clickSubmit();
|
||||
await login.clearSessionStorage();
|
||||
await page.goto(target.contentServerUrl, {
|
||||
waitUntil: 'load',
|
||||
});
|
||||
await login.denormalizeStoredEmail(email);
|
||||
await page.reload();
|
||||
|
||||
//Verify logged in on Settings page
|
||||
expect(await login.isUserLoggedIn()).toBe(true);
|
||||
});
|
||||
expect(await login.getPrefilledEmail()).toContain(email);
|
||||
await login.clickSignIn();
|
||||
|
||||
test('unverified cached signin redirects to confirm email', async ({
|
||||
target,
|
||||
}) => {
|
||||
const { page, login } = syncBrowserPages;
|
||||
const email_unverified = login.createEmail();
|
||||
await target.auth.signUp(email_unverified, password, {
|
||||
lang: 'en',
|
||||
preVerified: 'false',
|
||||
//Verify logged in on Settings page
|
||||
expect(await login.isUserLoggedIn()).toBe(true);
|
||||
|
||||
//Verify email is normalized
|
||||
const primary = await settings.primaryEmail.statusText();
|
||||
expect(primary).toEqual(email);
|
||||
});
|
||||
await page.goto(target.contentServerUrl, {
|
||||
waitUntil: 'load',
|
||||
|
||||
test('sign in once, use a different account', async ({ target }) => {
|
||||
const { page, login } = syncBrowserPages;
|
||||
await page.goto(target.contentServerUrl, {
|
||||
waitUntil: 'load',
|
||||
});
|
||||
await login.fillOutEmailFirstSignIn(email, password);
|
||||
|
||||
//Verify logged in on Settings page
|
||||
expect(await login.isUserLoggedIn()).toBe(true);
|
||||
await page.goto(target.contentServerUrl, {
|
||||
waitUntil: 'load',
|
||||
});
|
||||
//Check prefilled email
|
||||
expect(await login.getPrefilledEmail()).toContain(email);
|
||||
await login.useDifferentAccountLink();
|
||||
await login.fillOutEmailFirstSignIn(email2, password);
|
||||
|
||||
//Verify logged in on Settings page
|
||||
expect(await login.isUserLoggedIn()).toBe(true);
|
||||
|
||||
// testing to make sure cached signin comes back after a refresh
|
||||
await page.goto(target.contentServerUrl, {
|
||||
waitUntil: 'load',
|
||||
});
|
||||
//Check prefilled email
|
||||
expect(await login.getPrefilledEmail()).toContain(email2);
|
||||
});
|
||||
await login.fillOutEmailFirstSignIn(email_unverified, password);
|
||||
|
||||
//Verify sign up code header is visible
|
||||
await login.waitForSignUpCodeHeader();
|
||||
await page.goto(target.contentServerUrl, {
|
||||
waitUntil: 'load',
|
||||
test('expired cached credentials', async ({ target }) => {
|
||||
const { page, login } = syncBrowserPages;
|
||||
await page.goto(target.contentServerUrl, {
|
||||
waitUntil: 'load',
|
||||
});
|
||||
await login.fillOutEmailFirstSignIn(email, password);
|
||||
|
||||
//Verify logged in on Settings page
|
||||
expect(await login.isUserLoggedIn()).toBe(true);
|
||||
|
||||
await login.destroySession(email);
|
||||
await page.goto(target.contentServerUrl, {
|
||||
waitUntil: 'load',
|
||||
});
|
||||
|
||||
//Check prefilled email
|
||||
expect(await login.getPrefilledEmail()).toContain(email);
|
||||
await login.setPassword(password);
|
||||
await login.clickSubmit();
|
||||
|
||||
//Verify logged in on Settings page
|
||||
expect(await login.isUserLoggedIn()).toBe(true);
|
||||
});
|
||||
//Check prefilled email
|
||||
expect(await login.getPrefilledEmail()).toContain(email_unverified);
|
||||
await login.clickSignIn();
|
||||
|
||||
//Cached login should still go to email confirmation screen for unverified accounts
|
||||
await login.waitForSignUpCodeHeader();
|
||||
test('cached credentials that expire while on page', async ({ target }) => {
|
||||
const { page, login } = syncBrowserPages;
|
||||
await page.goto(target.contentServerUrl, {
|
||||
waitUntil: 'load',
|
||||
});
|
||||
await login.fillOutEmailFirstSignIn(email, password);
|
||||
|
||||
//Fill the code and submit
|
||||
await login.fillOutSignUpCode(email_unverified);
|
||||
//Verify logged in on Settings page
|
||||
expect(await login.isUserLoggedIn()).toBe(true);
|
||||
|
||||
//Verify logged in on Settings page
|
||||
expect(await login.isUserLoggedIn()).toBe(true);
|
||||
await page.goto(target.contentServerUrl, {
|
||||
waitUntil: 'load',
|
||||
});
|
||||
|
||||
//Check prefilled email
|
||||
expect(await login.getPrefilledEmail()).toContain(email);
|
||||
|
||||
await login.destroySession(email);
|
||||
await login.clickSignIn();
|
||||
|
||||
//Session expired error should show.
|
||||
expect(await login.signInError()).toContain(
|
||||
'Session expired. Sign in to continue.'
|
||||
);
|
||||
await login.setPassword(password);
|
||||
await login.clickSubmit();
|
||||
|
||||
//Verify logged in on Settings page
|
||||
expect(await login.isUserLoggedIn()).toBe(true);
|
||||
});
|
||||
|
||||
test('unverified cached signin redirects to confirm email', async ({
|
||||
target,
|
||||
}) => {
|
||||
const { page, login } = syncBrowserPages;
|
||||
const email_unverified = login.createEmail();
|
||||
await target.auth.signUp(email_unverified, password, {
|
||||
lang: 'en',
|
||||
preVerified: 'false',
|
||||
});
|
||||
await page.goto(target.contentServerUrl, {
|
||||
waitUntil: 'load',
|
||||
});
|
||||
await login.fillOutEmailFirstSignIn(email_unverified, password);
|
||||
|
||||
//Verify sign up code header is visible
|
||||
await login.waitForSignUpCodeHeader();
|
||||
await page.goto(target.contentServerUrl, {
|
||||
waitUntil: 'load',
|
||||
});
|
||||
//Check prefilled email
|
||||
expect(await login.getPrefilledEmail()).toContain(email_unverified);
|
||||
await login.clickSignIn();
|
||||
|
||||
//Cached login should still go to email confirmation screen for unverified accounts
|
||||
await login.waitForSignUpCodeHeader();
|
||||
|
||||
//Fill the code and submit
|
||||
await login.fillOutSignUpCode(email_unverified);
|
||||
|
||||
//Verify logged in on Settings page
|
||||
expect(await login.isUserLoggedIn()).toBe(true);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -1,227 +1,233 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
import { test, expect } from '../../../lib/fixtures/standard';
|
||||
|
||||
test.describe.configure({ mode: 'parallel' });
|
||||
|
||||
test.describe('coupon test', () => {
|
||||
test.beforeEach(() => {
|
||||
test.slow();
|
||||
});
|
||||
test.describe('severity-2 #smoke', () => {
|
||||
test.describe('coupon test', () => {
|
||||
test.beforeEach(() => {
|
||||
test.slow();
|
||||
});
|
||||
|
||||
test('apply an expired coupon', async ({ pages: { relier, subscribe } }, {
|
||||
project,
|
||||
}) => {
|
||||
test.skip(
|
||||
project.name === 'production',
|
||||
'test plan not yet available in prod'
|
||||
);
|
||||
await relier.goto();
|
||||
await relier.clickSubscribe6Month();
|
||||
test('apply an expired coupon', async ({ pages: { relier, subscribe } }, {
|
||||
project,
|
||||
}) => {
|
||||
test.skip(
|
||||
project.name === 'production',
|
||||
'test plan not yet available in prod'
|
||||
);
|
||||
await relier.goto();
|
||||
await relier.clickSubscribe6Month();
|
||||
|
||||
// 'autoexpired' coupon is an expired coupon for a 6mo plan
|
||||
await subscribe.addCouponCode('autoexpired');
|
||||
// 'autoexpired' coupon is an expired coupon for a 6mo plan
|
||||
await subscribe.addCouponCode('autoexpired');
|
||||
|
||||
// Verifying the correct error message
|
||||
expect(await subscribe.couponErrorMessageText()).toContain(
|
||||
'The code you entered has expired'
|
||||
);
|
||||
});
|
||||
// Verifying the correct error message
|
||||
expect(await subscribe.couponErrorMessageText()).toContain(
|
||||
'The code you entered has expired'
|
||||
);
|
||||
});
|
||||
|
||||
test('apply an invalid coupon', async ({ pages: { relier, subscribe } }, {
|
||||
project,
|
||||
}) => {
|
||||
test.skip(
|
||||
project.name === 'production',
|
||||
'test plan not yet available in prod'
|
||||
);
|
||||
await relier.goto();
|
||||
await relier.clickSubscribe6Month();
|
||||
test('apply an invalid coupon', async ({ pages: { relier, subscribe } }, {
|
||||
project,
|
||||
}) => {
|
||||
test.skip(
|
||||
project.name === 'production',
|
||||
'test plan not yet available in prod'
|
||||
);
|
||||
await relier.goto();
|
||||
await relier.clickSubscribe6Month();
|
||||
|
||||
// 'autoinvalid' coupon is an invalid coupon for a 6mo plan
|
||||
// But valid for a 12mo plan
|
||||
await subscribe.addCouponCode('autoinvalid');
|
||||
// 'autoinvalid' coupon is an invalid coupon for a 6mo plan
|
||||
// But valid for a 12mo plan
|
||||
await subscribe.addCouponCode('autoinvalid');
|
||||
|
||||
// Asserting that the code is invalid for a 6mo plan
|
||||
expect(await subscribe.couponErrorMessageText()).toContain(
|
||||
'The code you entered is invalid'
|
||||
);
|
||||
// Asserting that the code is invalid for a 6mo plan
|
||||
expect(await subscribe.couponErrorMessageText()).toContain(
|
||||
'The code you entered is invalid'
|
||||
);
|
||||
|
||||
// Adding the same code to a 12mo plan
|
||||
await relier.goto();
|
||||
await relier.clickSubscribe12Month();
|
||||
// Adding the same code to a 12mo plan
|
||||
await relier.goto();
|
||||
await relier.clickSubscribe12Month();
|
||||
|
||||
// 'autoinvalid' coupon is an invalid coupon for a 6mo plan
|
||||
// But valid for a 12mo plan
|
||||
await subscribe.addCouponCode('autoinvalid');
|
||||
// 'autoinvalid' coupon is an invalid coupon for a 6mo plan
|
||||
// But valid for a 12mo plan
|
||||
await subscribe.addCouponCode('autoinvalid');
|
||||
|
||||
// Verifying the coupon is valid with a discount line item
|
||||
expect(await subscribe.discountAppliedSuccess()).toBe(true);
|
||||
});
|
||||
// Verifying the coupon is valid with a discount line item
|
||||
expect(await subscribe.discountAppliedSuccess()).toBe(true);
|
||||
});
|
||||
|
||||
test('subscribe successfully with an invalid coupon', async ({
|
||||
pages: { relier, subscribe, login },
|
||||
}, { project }) => {
|
||||
test.skip(
|
||||
project.name === 'production',
|
||||
'no real payment method available in prod'
|
||||
);
|
||||
await relier.goto();
|
||||
await relier.clickSubscribe6Month();
|
||||
test('subscribe successfully with an invalid coupon', async ({
|
||||
pages: { relier, subscribe, login },
|
||||
}, { project }) => {
|
||||
test.skip(
|
||||
project.name === 'production',
|
||||
'no real payment method available in prod'
|
||||
);
|
||||
await relier.goto();
|
||||
await relier.clickSubscribe6Month();
|
||||
|
||||
// 'autoinvalid' coupon is an invalid coupon for a 6mo plan
|
||||
await subscribe.addCouponCode('autoinvalid');
|
||||
// 'autoinvalid' coupon is an invalid coupon for a 6mo plan
|
||||
await subscribe.addCouponCode('autoinvalid');
|
||||
|
||||
// Asserting that the code is invalid for a 6m plan
|
||||
expect(await subscribe.couponErrorMessageText()).toContain(
|
||||
'The code you entered is invalid'
|
||||
);
|
||||
// Asserting that the code is invalid for a 6m plan
|
||||
expect(await subscribe.couponErrorMessageText()).toContain(
|
||||
'The code you entered is invalid'
|
||||
);
|
||||
|
||||
// Successfully subscribe
|
||||
await subscribe.setConfirmPaymentCheckbox();
|
||||
await subscribe.setFullName();
|
||||
await subscribe.setCreditCardInfo();
|
||||
await subscribe.clickPayNow();
|
||||
await subscribe.submit();
|
||||
await relier.goto();
|
||||
await relier.clickEmailFirst();
|
||||
await login.submit();
|
||||
expect(await relier.isPro()).toBe(true);
|
||||
});
|
||||
// Successfully subscribe
|
||||
await subscribe.setConfirmPaymentCheckbox();
|
||||
await subscribe.setFullName();
|
||||
await subscribe.setCreditCardInfo();
|
||||
await subscribe.clickPayNow();
|
||||
await subscribe.submit();
|
||||
await relier.goto();
|
||||
await relier.clickEmailFirst();
|
||||
await login.submit();
|
||||
expect(await relier.isPro()).toBe(true);
|
||||
});
|
||||
|
||||
test('subscribe successfully with a forever discount coupon', async ({
|
||||
pages: { relier, subscribe, login },
|
||||
}, { project }) => {
|
||||
test.skip(
|
||||
project.name === 'production',
|
||||
'no real payment method available in prod'
|
||||
);
|
||||
await relier.goto();
|
||||
await relier.clickSubscribe6Month();
|
||||
test('subscribe successfully with a forever discount coupon', async ({
|
||||
pages: { relier, subscribe, login },
|
||||
}, { project }) => {
|
||||
test.skip(
|
||||
project.name === 'production',
|
||||
'no real payment method available in prod'
|
||||
);
|
||||
await relier.goto();
|
||||
await relier.clickSubscribe6Month();
|
||||
|
||||
// 'auto10pforever' is a 10% forever discount coupon for a 6mo plan
|
||||
await subscribe.addCouponCode('auto10pforever');
|
||||
// 'auto10pforever' is a 10% forever discount coupon for a 6mo plan
|
||||
await subscribe.addCouponCode('auto10pforever');
|
||||
|
||||
// Verify the coupon is applied successfully
|
||||
expect(await subscribe.discountAppliedSuccess()).toBe(true);
|
||||
// Verify the coupon is applied successfully
|
||||
expect(await subscribe.discountAppliedSuccess()).toBe(true);
|
||||
|
||||
// Verify the line items after applying discount
|
||||
expect(await subscribe.discountListPrice()).toBe(true);
|
||||
expect(await subscribe.discountLineItem()).toBe(true);
|
||||
// Verify the line items after applying discount
|
||||
expect(await subscribe.discountListPrice()).toBe(true);
|
||||
expect(await subscribe.discountLineItem()).toBe(true);
|
||||
|
||||
// Successfully subscribe
|
||||
await subscribe.setConfirmPaymentCheckbox();
|
||||
await subscribe.setFullName();
|
||||
await subscribe.setCreditCardInfo();
|
||||
await subscribe.clickPayNow();
|
||||
await subscribe.submit();
|
||||
await relier.goto();
|
||||
await relier.clickEmailFirst();
|
||||
await login.submit();
|
||||
expect(await relier.isPro()).toBe(true);
|
||||
});
|
||||
// Successfully subscribe
|
||||
await subscribe.setConfirmPaymentCheckbox();
|
||||
await subscribe.setFullName();
|
||||
await subscribe.setCreditCardInfo();
|
||||
await subscribe.clickPayNow();
|
||||
await subscribe.submit();
|
||||
await relier.goto();
|
||||
await relier.clickEmailFirst();
|
||||
await login.submit();
|
||||
expect(await relier.isPro()).toBe(true);
|
||||
});
|
||||
|
||||
test('subscribe with a one time discount coupon', async ({
|
||||
pages: { relier, subscribe, login },
|
||||
}, { project }) => {
|
||||
test.skip(
|
||||
project.name === 'production',
|
||||
'no real payment method available in prod'
|
||||
);
|
||||
await relier.goto();
|
||||
await relier.clickSubscribe12Month();
|
||||
test('subscribe with a one time discount coupon', async ({
|
||||
pages: { relier, subscribe, login },
|
||||
}, { project }) => {
|
||||
test.skip(
|
||||
project.name === 'production',
|
||||
'no real payment method available in prod'
|
||||
);
|
||||
await relier.goto();
|
||||
await relier.clickSubscribe12Month();
|
||||
|
||||
// 'auto50ponetime' is a one time 50% discount coupon for a 12mo plan
|
||||
await subscribe.addCouponCode('auto50ponetime');
|
||||
// 'auto50ponetime' is a one time 50% discount coupon for a 12mo plan
|
||||
await subscribe.addCouponCode('auto50ponetime');
|
||||
|
||||
// Verify the coupon is applied successfully
|
||||
expect(await subscribe.discountAppliedSuccess()).toBe(true);
|
||||
expect(await subscribe.oneTimeDiscountSuccess()).toBe(true);
|
||||
// Verify the coupon is applied successfully
|
||||
expect(await subscribe.discountAppliedSuccess()).toBe(true);
|
||||
expect(await subscribe.oneTimeDiscountSuccess()).toBe(true);
|
||||
|
||||
// Verify the line items is visible after applying discount
|
||||
expect(await subscribe.discountListPrice()).toBe(true);
|
||||
expect(await subscribe.discountLineItem()).toBe(true);
|
||||
// Verify the line items is visible after applying discount
|
||||
expect(await subscribe.discountListPrice()).toBe(true);
|
||||
expect(await subscribe.discountLineItem()).toBe(true);
|
||||
|
||||
// Successfully subscribe
|
||||
await subscribe.setConfirmPaymentCheckbox();
|
||||
await subscribe.setFullName();
|
||||
await subscribe.setCreditCardInfo();
|
||||
await subscribe.clickPayNow();
|
||||
await subscribe.submit();
|
||||
await relier.goto();
|
||||
await relier.clickEmailFirst();
|
||||
await login.submit();
|
||||
expect(await relier.isPro()).toBe(true);
|
||||
});
|
||||
// Successfully subscribe
|
||||
await subscribe.setConfirmPaymentCheckbox();
|
||||
await subscribe.setFullName();
|
||||
await subscribe.setCreditCardInfo();
|
||||
await subscribe.clickPayNow();
|
||||
await subscribe.submit();
|
||||
await relier.goto();
|
||||
await relier.clickEmailFirst();
|
||||
await login.submit();
|
||||
expect(await relier.isPro()).toBe(true);
|
||||
});
|
||||
|
||||
test('subscribe with credit card and use coupon', async ({
|
||||
pages: { relier, login, subscribe },
|
||||
}, { project }) => {
|
||||
test.skip(
|
||||
project.name === 'production',
|
||||
'no real payment method available in prod'
|
||||
);
|
||||
await relier.goto();
|
||||
await relier.clickSubscribe6Month();
|
||||
test('subscribe with credit card and use coupon', async ({
|
||||
pages: { relier, login, subscribe },
|
||||
}, { project }) => {
|
||||
test.skip(
|
||||
project.name === 'production',
|
||||
'no real payment method available in prod'
|
||||
);
|
||||
await relier.goto();
|
||||
await relier.clickSubscribe6Month();
|
||||
|
||||
// 'auto10pforever' is a 10% forever discount coupon for a 6mo plan
|
||||
await subscribe.addCouponCode('auto10pforever');
|
||||
await subscribe.setConfirmPaymentCheckbox();
|
||||
await subscribe.setFullName();
|
||||
await subscribe.setCreditCardInfo();
|
||||
await subscribe.clickPayNow();
|
||||
await subscribe.submit();
|
||||
await relier.goto();
|
||||
await relier.clickEmailFirst();
|
||||
await login.submit();
|
||||
expect(await relier.isPro()).toBe(true);
|
||||
});
|
||||
// 'auto10pforever' is a 10% forever discount coupon for a 6mo plan
|
||||
await subscribe.addCouponCode('auto10pforever');
|
||||
await subscribe.setConfirmPaymentCheckbox();
|
||||
await subscribe.setFullName();
|
||||
await subscribe.setCreditCardInfo();
|
||||
await subscribe.clickPayNow();
|
||||
await subscribe.submit();
|
||||
await relier.goto();
|
||||
await relier.clickEmailFirst();
|
||||
await login.submit();
|
||||
expect(await relier.isPro()).toBe(true);
|
||||
});
|
||||
|
||||
test('subscribe with paypal and use coupon', async ({
|
||||
pages: { relier, login, subscribe },
|
||||
}, { project }) => {
|
||||
test.skip(
|
||||
project.name === 'production',
|
||||
'no real payment method available in prod'
|
||||
);
|
||||
await relier.goto();
|
||||
await relier.clickSubscribe12Month();
|
||||
test('subscribe with paypal and use coupon', async ({
|
||||
pages: { relier, login, subscribe },
|
||||
}, { project }) => {
|
||||
test.skip(
|
||||
project.name === 'production',
|
||||
'no real payment method available in prod'
|
||||
);
|
||||
await relier.goto();
|
||||
await relier.clickSubscribe12Month();
|
||||
|
||||
// 'auto50ponetime' is a one time 50% discount coupon for a 12mo plan
|
||||
await subscribe.addCouponCode('auto50ponetime');
|
||||
await subscribe.setConfirmPaymentCheckbox();
|
||||
await subscribe.setPayPalInfo();
|
||||
await subscribe.submit();
|
||||
await relier.goto();
|
||||
await relier.clickEmailFirst();
|
||||
await login.submit();
|
||||
expect(await relier.isPro()).toBe(true);
|
||||
});
|
||||
// 'auto50ponetime' is a one time 50% discount coupon for a 12mo plan
|
||||
await subscribe.addCouponCode('auto50ponetime');
|
||||
await subscribe.setConfirmPaymentCheckbox();
|
||||
await subscribe.setPayPalInfo();
|
||||
await subscribe.submit();
|
||||
await relier.goto();
|
||||
await relier.clickEmailFirst();
|
||||
await login.submit();
|
||||
expect(await relier.isPro()).toBe(true);
|
||||
});
|
||||
|
||||
test('remove a coupon and verify', async ({
|
||||
pages: { relier, subscribe, login },
|
||||
}, { project }) => {
|
||||
test.skip(
|
||||
project.name === 'production',
|
||||
'test plan not yet available in prod'
|
||||
);
|
||||
test('remove a coupon and verify', async ({
|
||||
pages: { relier, subscribe, login },
|
||||
}, { project }) => {
|
||||
test.skip(
|
||||
project.name === 'production',
|
||||
'test plan not yet available in prod'
|
||||
);
|
||||
|
||||
await relier.goto();
|
||||
await relier.clickSubscribe12Month();
|
||||
await relier.goto();
|
||||
await relier.clickSubscribe12Month();
|
||||
|
||||
// 'auto50ponetime' is a one time 50% discount coupon for a 12mo plan
|
||||
await subscribe.addCouponCode('auto50ponetime');
|
||||
// 'auto50ponetime' is a one time 50% discount coupon for a 12mo plan
|
||||
await subscribe.addCouponCode('auto50ponetime');
|
||||
|
||||
// Verify the coupon is applied successfully
|
||||
expect(await subscribe.discountAppliedSuccess()).toBe(true);
|
||||
expect(await subscribe.oneTimeDiscountSuccess()).toBe(true);
|
||||
// Verify the coupon is applied successfully
|
||||
expect(await subscribe.discountAppliedSuccess()).toBe(true);
|
||||
expect(await subscribe.oneTimeDiscountSuccess()).toBe(true);
|
||||
|
||||
// Verify the line items is visible after applying discount
|
||||
expect(await subscribe.discountListPrice()).toBe(true);
|
||||
expect(await subscribe.discountLineItem()).toBe(true);
|
||||
// Verify the line items is visible after applying discount
|
||||
expect(await subscribe.discountListPrice()).toBe(true);
|
||||
expect(await subscribe.discountLineItem()).toBe(true);
|
||||
|
||||
// Remove the coupon
|
||||
await subscribe.removeCouponCode();
|
||||
// Remove the coupon
|
||||
await subscribe.removeCouponCode();
|
||||
|
||||
// Verify the discount is removed
|
||||
expect(await subscribe.discountLineItem()).toBe(false);
|
||||
// Verify the discount is removed
|
||||
expect(await subscribe.discountLineItem()).toBe(false);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -1,193 +1,199 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
import { test, expect } from '../../../lib/fixtures/standard';
|
||||
|
||||
test.describe.configure({ mode: 'parallel' });
|
||||
|
||||
test.describe('resubscription test', () => {
|
||||
test.beforeEach(() => {
|
||||
test.slow();
|
||||
test.describe('severity-2 #smoke', () => {
|
||||
test.describe('resubscription test', () => {
|
||||
test.beforeEach(() => {
|
||||
test.slow();
|
||||
});
|
||||
|
||||
test('resubscribe successfully with the same coupon after canceling for stripe', async ({
|
||||
page,
|
||||
pages: { relier, subscribe, login, settings, subscriptionManagement },
|
||||
}, { project }) => {
|
||||
test.skip(
|
||||
project.name === 'production',
|
||||
'no real payment method available in prod'
|
||||
);
|
||||
await relier.goto();
|
||||
await relier.clickSubscribe6Month();
|
||||
|
||||
// 'auto10pforever' is a 10% forever discount coupon for a 6mo plan
|
||||
await subscribe.addCouponCode('auto10pforever');
|
||||
|
||||
// Verify the coupon is applied successfully
|
||||
expect(await subscribe.discountAppliedSuccess()).toBe(true);
|
||||
|
||||
const total = await subscribe.getTotalPrice();
|
||||
|
||||
//Subscribe successfully with Stripe
|
||||
await subscribe.setConfirmPaymentCheckbox();
|
||||
await subscribe.setFullName();
|
||||
await subscribe.setCreditCardInfo();
|
||||
await subscribe.clickPayNow();
|
||||
await subscribe.submit();
|
||||
|
||||
//Login to FxA account
|
||||
await login.goto();
|
||||
await login.clickSignIn();
|
||||
const subscriptionPage = await settings.clickPaidSubscriptions();
|
||||
subscriptionManagement.page = subscriptionPage;
|
||||
|
||||
//Verify no coupon details are visible
|
||||
expect(await subscriptionManagement.subscriptionDetails()).not.toContain(
|
||||
'Promo'
|
||||
);
|
||||
|
||||
//Cancel subscription and then resubscribe
|
||||
await subscriptionManagement.cancelSubscription();
|
||||
await subscriptionManagement.resubscribe();
|
||||
|
||||
//Verify that the resubscription has the same coupon applied
|
||||
expect(await subscriptionManagement.getResubscriptionPrice()).toEqual(
|
||||
total
|
||||
);
|
||||
|
||||
//Verify no coupon details are visible
|
||||
expect(await subscriptionManagement.subscriptionDetails()).not.toContain(
|
||||
'Promo'
|
||||
);
|
||||
});
|
||||
|
||||
test('resubscribe successfully with the same coupon after canceling for paypal', async ({
|
||||
page,
|
||||
pages: { relier, subscribe, login, settings, subscriptionManagement },
|
||||
}, { project }) => {
|
||||
test.skip(
|
||||
project.name === 'production',
|
||||
'no real payment method available in prod'
|
||||
);
|
||||
await relier.goto();
|
||||
await relier.clickSubscribe6Month();
|
||||
|
||||
// 'auto10pforever' is a 10% forever discount coupon for a 6mo plan
|
||||
await subscribe.addCouponCode('auto10pforever');
|
||||
|
||||
// Verify the coupon is applied successfully
|
||||
expect(await subscribe.discountAppliedSuccess()).toBe(true);
|
||||
|
||||
const total = await subscribe.getTotalPrice();
|
||||
|
||||
//Subscribe successfully using Paypal
|
||||
await subscribe.setConfirmPaymentCheckbox();
|
||||
await subscribe.setPayPalInfo();
|
||||
await subscribe.submit();
|
||||
|
||||
//Login to FxA account
|
||||
await login.goto();
|
||||
await login.clickSignIn();
|
||||
const subscriptionPage = await settings.clickPaidSubscriptions();
|
||||
subscriptionManagement.page = subscriptionPage;
|
||||
|
||||
//Verify no coupon details are visible
|
||||
expect(await subscriptionManagement.subscriptionDetails()).not.toContain(
|
||||
'Promo'
|
||||
);
|
||||
|
||||
//Cancel subscription and then resubscribe
|
||||
await subscriptionManagement.cancelSubscription();
|
||||
await subscriptionManagement.resubscribe();
|
||||
|
||||
//Verify that the resubscription has the same coupon applied
|
||||
expect(await subscriptionManagement.getResubscriptionPrice()).toEqual(
|
||||
total
|
||||
);
|
||||
|
||||
//Verify no coupon details are visible
|
||||
expect(await subscriptionManagement.subscriptionDetails()).not.toContain(
|
||||
'Promo'
|
||||
);
|
||||
});
|
||||
|
||||
test('update mode of payment for stripe', async ({
|
||||
page,
|
||||
pages: { relier, subscribe, login, settings, subscriptionManagement },
|
||||
}, { project }) => {
|
||||
test.skip(
|
||||
project.name === 'production',
|
||||
'no real payment method available in prod'
|
||||
);
|
||||
await relier.goto();
|
||||
await relier.clickSubscribe6Month();
|
||||
|
||||
// 'auto10pforever' is a 10% forever discount coupon for a 6mo plan
|
||||
await subscribe.addCouponCode('auto10pforever');
|
||||
|
||||
//Subscribe successfully
|
||||
await subscribe.setConfirmPaymentCheckbox();
|
||||
await subscribe.setFullName();
|
||||
await subscribe.setCreditCardInfo();
|
||||
await subscribe.clickPayNow();
|
||||
await subscribe.submit();
|
||||
|
||||
//Login to FxA account
|
||||
await login.goto();
|
||||
await login.clickSignIn();
|
||||
const subscriptionPage = await settings.clickPaidSubscriptions();
|
||||
subscriptionManagement.page = subscriptionPage;
|
||||
|
||||
//Change stripe card information
|
||||
await subscriptionManagement.changeStripeCardDetails();
|
||||
|
||||
//Verify that the card info is updated
|
||||
expect(await subscriptionManagement.getCardInfo()).toContain('4444');
|
||||
});
|
||||
|
||||
//Disable as paypal sandbox is taking a long time to load
|
||||
/*test('update mode of payment for paypal', async ({
|
||||
page,
|
||||
pages: { relier, subscribe, login, settings, subscriptionManagement },
|
||||
}, { project }) => {
|
||||
test.skip(
|
||||
project.name !== 'local',
|
||||
'no real payment method available in prod'
|
||||
);
|
||||
await relier.goto();
|
||||
await relier.clickSubscribe();
|
||||
|
||||
// 'auto10pforever' is a 10% forever discount coupon for a 6mo plan
|
||||
await subscribe.addCouponCode('auto10pforever');
|
||||
|
||||
//Subscribe successfully
|
||||
await subscribe.setConfirmPaymentCheckbox();
|
||||
await subscribe.setPayPalInfo();
|
||||
await subscribe.submit();
|
||||
|
||||
//Login to FxA account
|
||||
await login.goto();
|
||||
await login.clickSignIn();
|
||||
const subscriptionPage = await settings.clickPaidSubscriptions();
|
||||
subscriptionManagement.page = subscriptionPage;
|
||||
|
||||
//Change Paypal information
|
||||
const paypalPage = await subscriptionManagement.clickPaypalChange();
|
||||
subscriptionManagement.page = paypalPage;
|
||||
|
||||
//Login to Paypal sandbox
|
||||
await subscriptionManagement.loginPaypal();
|
||||
|
||||
//Verify the account as 'CREDIT UNION'
|
||||
expect(await subscriptionManagement.checkPaypalAccount()).toContain(
|
||||
'CREDIT UNION'
|
||||
);
|
||||
|
||||
//Change account from 'Credit Union' to 'Visa'
|
||||
await subscriptionManagement.updatePaypalAccount();
|
||||
|
||||
//Added this timeout wait for page to be loaded correctly
|
||||
await page.waitForTimeout(2000);
|
||||
|
||||
//Verify that the payment info is updated
|
||||
expect(await subscriptionManagement.checkPaypalAccount()).toContain('Visa');
|
||||
});*/
|
||||
});
|
||||
|
||||
test('resubscribe successfully with the same coupon after canceling for stripe', async ({
|
||||
page,
|
||||
pages: { relier, subscribe, login, settings, subscriptionManagement },
|
||||
}, { project }) => {
|
||||
test.skip(
|
||||
project.name === 'production',
|
||||
'no real payment method available in prod'
|
||||
);
|
||||
await relier.goto();
|
||||
await relier.clickSubscribe6Month();
|
||||
|
||||
// 'auto10pforever' is a 10% forever discount coupon for a 6mo plan
|
||||
await subscribe.addCouponCode('auto10pforever');
|
||||
|
||||
// Verify the coupon is applied successfully
|
||||
expect(await subscribe.discountAppliedSuccess()).toBe(true);
|
||||
|
||||
const total = await subscribe.getTotalPrice();
|
||||
|
||||
//Subscribe successfully with Stripe
|
||||
await subscribe.setConfirmPaymentCheckbox();
|
||||
await subscribe.setFullName();
|
||||
await subscribe.setCreditCardInfo();
|
||||
await subscribe.clickPayNow();
|
||||
await subscribe.submit();
|
||||
|
||||
//Login to FxA account
|
||||
await login.goto();
|
||||
await login.clickSignIn();
|
||||
const subscriptionPage = await settings.clickPaidSubscriptions();
|
||||
subscriptionManagement.page = subscriptionPage;
|
||||
|
||||
//Verify no coupon details are visible
|
||||
expect(await subscriptionManagement.subscriptionDetails()).not.toContain(
|
||||
'Promo'
|
||||
);
|
||||
|
||||
//Cancel subscription and then resubscribe
|
||||
await subscriptionManagement.cancelSubscription();
|
||||
await subscriptionManagement.resubscribe();
|
||||
|
||||
//Verify that the resubscription has the same coupon applied
|
||||
expect(await subscriptionManagement.getResubscriptionPrice()).toEqual(
|
||||
total
|
||||
);
|
||||
|
||||
//Verify no coupon details are visible
|
||||
expect(await subscriptionManagement.subscriptionDetails()).not.toContain(
|
||||
'Promo'
|
||||
);
|
||||
});
|
||||
|
||||
test('resubscribe successfully with the same coupon after canceling for paypal', async ({
|
||||
page,
|
||||
pages: { relier, subscribe, login, settings, subscriptionManagement },
|
||||
}, { project }) => {
|
||||
test.skip(
|
||||
project.name === 'production',
|
||||
'no real payment method available in prod'
|
||||
);
|
||||
await relier.goto();
|
||||
await relier.clickSubscribe6Month();
|
||||
|
||||
// 'auto10pforever' is a 10% forever discount coupon for a 6mo plan
|
||||
await subscribe.addCouponCode('auto10pforever');
|
||||
|
||||
// Verify the coupon is applied successfully
|
||||
expect(await subscribe.discountAppliedSuccess()).toBe(true);
|
||||
|
||||
const total = await subscribe.getTotalPrice();
|
||||
|
||||
//Subscribe successfully using Paypal
|
||||
await subscribe.setConfirmPaymentCheckbox();
|
||||
await subscribe.setPayPalInfo();
|
||||
await subscribe.submit();
|
||||
|
||||
//Login to FxA account
|
||||
await login.goto();
|
||||
await login.clickSignIn();
|
||||
const subscriptionPage = await settings.clickPaidSubscriptions();
|
||||
subscriptionManagement.page = subscriptionPage;
|
||||
|
||||
//Verify no coupon details are visible
|
||||
expect(await subscriptionManagement.subscriptionDetails()).not.toContain(
|
||||
'Promo'
|
||||
);
|
||||
|
||||
//Cancel subscription and then resubscribe
|
||||
await subscriptionManagement.cancelSubscription();
|
||||
await subscriptionManagement.resubscribe();
|
||||
|
||||
//Verify that the resubscription has the same coupon applied
|
||||
expect(await subscriptionManagement.getResubscriptionPrice()).toEqual(
|
||||
total
|
||||
);
|
||||
|
||||
//Verify no coupon details are visible
|
||||
expect(await subscriptionManagement.subscriptionDetails()).not.toContain(
|
||||
'Promo'
|
||||
);
|
||||
});
|
||||
|
||||
test('update mode of payment for stripe', async ({
|
||||
page,
|
||||
pages: { relier, subscribe, login, settings, subscriptionManagement },
|
||||
}, { project }) => {
|
||||
test.skip(
|
||||
project.name === 'production',
|
||||
'no real payment method available in prod'
|
||||
);
|
||||
await relier.goto();
|
||||
await relier.clickSubscribe6Month();
|
||||
|
||||
// 'auto10pforever' is a 10% forever discount coupon for a 6mo plan
|
||||
await subscribe.addCouponCode('auto10pforever');
|
||||
|
||||
//Subscribe successfully
|
||||
await subscribe.setConfirmPaymentCheckbox();
|
||||
await subscribe.setFullName();
|
||||
await subscribe.setCreditCardInfo();
|
||||
await subscribe.clickPayNow();
|
||||
await subscribe.submit();
|
||||
|
||||
//Login to FxA account
|
||||
await login.goto();
|
||||
await login.clickSignIn();
|
||||
const subscriptionPage = await settings.clickPaidSubscriptions();
|
||||
subscriptionManagement.page = subscriptionPage;
|
||||
|
||||
//Change stripe card information
|
||||
await subscriptionManagement.changeStripeCardDetails();
|
||||
|
||||
//Verify that the card info is updated
|
||||
expect(await subscriptionManagement.getCardInfo()).toContain('4444');
|
||||
});
|
||||
|
||||
//Disable as paypal sandbox is taking a long time to load
|
||||
/*test('update mode of payment for paypal', async ({
|
||||
page,
|
||||
pages: { relier, subscribe, login, settings, subscriptionManagement },
|
||||
}, { project }) => {
|
||||
test.skip(
|
||||
project.name !== 'local',
|
||||
'no real payment method available in prod'
|
||||
);
|
||||
await relier.goto();
|
||||
await relier.clickSubscribe();
|
||||
|
||||
// 'auto10pforever' is a 10% forever discount coupon for a 6mo plan
|
||||
await subscribe.addCouponCode('auto10pforever');
|
||||
|
||||
//Subscribe successfully
|
||||
await subscribe.setConfirmPaymentCheckbox();
|
||||
await subscribe.setPayPalInfo();
|
||||
await subscribe.submit();
|
||||
|
||||
//Login to FxA account
|
||||
await login.goto();
|
||||
await login.clickSignIn();
|
||||
const subscriptionPage = await settings.clickPaidSubscriptions();
|
||||
subscriptionManagement.page = subscriptionPage;
|
||||
|
||||
//Change Paypal information
|
||||
const paypalPage = await subscriptionManagement.clickPaypalChange();
|
||||
subscriptionManagement.page = paypalPage;
|
||||
|
||||
//Login to Paypal sandbox
|
||||
await subscriptionManagement.loginPaypal();
|
||||
|
||||
//Verify the account as 'CREDIT UNION'
|
||||
expect(await subscriptionManagement.checkPaypalAccount()).toContain(
|
||||
'CREDIT UNION'
|
||||
);
|
||||
|
||||
//Change account from 'Credit Union' to 'Visa'
|
||||
await subscriptionManagement.updatePaypalAccount();
|
||||
|
||||
//Added this timeout wait for page to be loaded correctly
|
||||
await page.waitForTimeout(2000);
|
||||
|
||||
//Verify that the payment info is updated
|
||||
expect(await subscriptionManagement.checkPaypalAccount()).toContain('Visa');
|
||||
});*/
|
||||
});
|
||||
|
|
|
@ -1,71 +1,77 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
import { expect, test } from '../../../lib/fixtures/standard';
|
||||
import { MetricsObserver } from '../../../lib/metrics';
|
||||
|
||||
test.describe('ui functionality', () => {
|
||||
let metricsObserver: MetricsObserver;
|
||||
test.describe('severity-2 #smoke', () => {
|
||||
test.describe('ui functionality', () => {
|
||||
let metricsObserver: MetricsObserver;
|
||||
|
||||
test.beforeEach(({ pages: { subscribe } }) => {
|
||||
test.slow();
|
||||
metricsObserver = new MetricsObserver(subscribe);
|
||||
metricsObserver.startTracking();
|
||||
});
|
||||
|
||||
test('verify plan change funnel metrics & coupon feature not available when changing plans', async ({
|
||||
page,
|
||||
pages: { relier, subscribe },
|
||||
}, { project }) => {
|
||||
test.skip(
|
||||
project.name === 'production',
|
||||
'no real payment method available in prod'
|
||||
);
|
||||
await relier.goto();
|
||||
await relier.clickSubscribe6Month();
|
||||
|
||||
// Verify discount section is displayed
|
||||
expect(await subscribe.discountTextbox()).toBe(true);
|
||||
|
||||
// 'auto10pforever' is a 10% forever discount coupon for a 6mo plan
|
||||
await subscribe.addCouponCode('auto10pforever');
|
||||
|
||||
// Verify the coupon is applied successfully
|
||||
expect(await subscribe.discountAppliedSuccess()).toBe(true);
|
||||
|
||||
//Subscribe successfully with Stripe
|
||||
await subscribe.setConfirmPaymentCheckbox();
|
||||
await subscribe.setFullName();
|
||||
await subscribe.setCreditCardInfo();
|
||||
await subscribe.clickPayNow();
|
||||
await subscribe.submit();
|
||||
await relier.goto();
|
||||
|
||||
//Change the plan
|
||||
await relier.clickSubscribe12Month();
|
||||
|
||||
//Verify Discount section is not displayed
|
||||
expect(await subscribe.planUpgradeDetails()).not.toContain('Promo');
|
||||
|
||||
//Submit the changes
|
||||
await subscribe.clickConfirmPlanChange();
|
||||
await subscribe.clickPayNow();
|
||||
await subscribe.submit();
|
||||
|
||||
//Verify the subscription is successful
|
||||
expect(await subscribe.isSubscriptionSuccess()).toBe(true);
|
||||
|
||||
// check conversion funnel metrics
|
||||
const expectedEventTypes = [
|
||||
'amplitude.subPaySetup.view',
|
||||
'amplitude.subPaySetup.engage',
|
||||
'amplitude.subPaySetup.submit',
|
||||
'amplitude.subPaySetup.success',
|
||||
'amplitude.subPaySubChange.view',
|
||||
'amplitude.subPaySubChange.engage',
|
||||
'amplitude.subPaySubChange.submit',
|
||||
'amplitude.subPaySubChange.success',
|
||||
];
|
||||
const actualEventTypes = metricsObserver.rawEvents.map((event) => {
|
||||
return event.type;
|
||||
test.beforeEach(({ pages: { subscribe } }) => {
|
||||
test.slow();
|
||||
metricsObserver = new MetricsObserver(subscribe);
|
||||
metricsObserver.startTracking();
|
||||
});
|
||||
|
||||
test('verify plan change funnel metrics & coupon feature not available when changing plans', async ({
|
||||
page,
|
||||
pages: { relier, subscribe },
|
||||
}, { project }) => {
|
||||
test.skip(
|
||||
project.name === 'production',
|
||||
'no real payment method available in prod'
|
||||
);
|
||||
await relier.goto();
|
||||
await relier.clickSubscribe6Month();
|
||||
|
||||
// Verify discount section is displayed
|
||||
expect(await subscribe.discountTextbox()).toBe(true);
|
||||
|
||||
// 'auto10pforever' is a 10% forever discount coupon for a 6mo plan
|
||||
await subscribe.addCouponCode('auto10pforever');
|
||||
|
||||
// Verify the coupon is applied successfully
|
||||
expect(await subscribe.discountAppliedSuccess()).toBe(true);
|
||||
|
||||
//Subscribe successfully with Stripe
|
||||
await subscribe.setConfirmPaymentCheckbox();
|
||||
await subscribe.setFullName();
|
||||
await subscribe.setCreditCardInfo();
|
||||
await subscribe.clickPayNow();
|
||||
await subscribe.submit();
|
||||
await relier.goto();
|
||||
|
||||
//Change the plan
|
||||
await relier.clickSubscribe12Month();
|
||||
|
||||
//Verify Discount section is not displayed
|
||||
expect(await subscribe.planUpgradeDetails()).not.toContain('Promo');
|
||||
|
||||
//Submit the changes
|
||||
await subscribe.clickConfirmPlanChange();
|
||||
await subscribe.clickPayNow();
|
||||
await subscribe.submit();
|
||||
|
||||
//Verify the subscription is successful
|
||||
expect(await subscribe.isSubscriptionSuccess()).toBe(true);
|
||||
|
||||
// check conversion funnel metrics
|
||||
const expectedEventTypes = [
|
||||
'amplitude.subPaySetup.view',
|
||||
'amplitude.subPaySetup.engage',
|
||||
'amplitude.subPaySetup.submit',
|
||||
'amplitude.subPaySetup.success',
|
||||
'amplitude.subPaySubChange.view',
|
||||
'amplitude.subPaySubChange.engage',
|
||||
'amplitude.subPaySubChange.submit',
|
||||
'amplitude.subPaySubChange.success',
|
||||
];
|
||||
const actualEventTypes = metricsObserver.rawEvents.map((event) => {
|
||||
return event.type;
|
||||
});
|
||||
expect(actualEventTypes).toMatchObject(expectedEventTypes);
|
||||
});
|
||||
expect(actualEventTypes).toMatchObject(expectedEventTypes);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -1,205 +1,51 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
import { expect, test } from '../../lib/fixtures/standard';
|
||||
import { MetricsObserver } from '../../lib/metrics';
|
||||
|
||||
test.describe.configure({ mode: 'parallel' });
|
||||
|
||||
test.describe('subscription test with cc and paypal', () => {
|
||||
let metricsObserver: MetricsObserver;
|
||||
test.describe('severity-2 #smoke', () => {
|
||||
test.describe('subscription test with cc and paypal', () => {
|
||||
let metricsObserver: MetricsObserver;
|
||||
|
||||
test.beforeEach(({ pages: { subscribe } }) => {
|
||||
test.slow();
|
||||
metricsObserver = new MetricsObserver(subscribe);
|
||||
metricsObserver.startTracking();
|
||||
});
|
||||
|
||||
test('subscribe with credit card and login to product', async ({
|
||||
pages: { relier, login, subscribe },
|
||||
}, { project }) => {
|
||||
test.skip(
|
||||
project.name === 'production',
|
||||
'no real payment method available in prod'
|
||||
);
|
||||
await relier.goto();
|
||||
await relier.clickSubscribe();
|
||||
await subscribe.setConfirmPaymentCheckbox();
|
||||
await subscribe.setFullName();
|
||||
await subscribe.setCreditCardInfo();
|
||||
await subscribe.clickPayNow();
|
||||
await subscribe.submit();
|
||||
await relier.goto();
|
||||
await relier.clickEmailFirst();
|
||||
await login.submit();
|
||||
expect(await relier.isPro()).toBe(true);
|
||||
});
|
||||
|
||||
test('subscribe with credit card after initial failed subscription & verify existing user checkout funnel metrics', async ({
|
||||
pages: { relier, login, subscribe },
|
||||
}, { project }) => {
|
||||
test.skip(
|
||||
project.name === 'production',
|
||||
'no real payment method available in prod'
|
||||
);
|
||||
await relier.goto();
|
||||
await relier.clickSubscribe();
|
||||
await subscribe.setConfirmPaymentCheckbox();
|
||||
await subscribe.setFullName();
|
||||
await subscribe.setFailedCreditCardInfo();
|
||||
await subscribe.clickPayNow();
|
||||
await subscribe.clickTryAgain();
|
||||
await subscribe.setCreditCardInfo();
|
||||
await subscribe.clickPayNow();
|
||||
await subscribe.submit();
|
||||
await relier.goto();
|
||||
await relier.clickEmailFirst();
|
||||
await login.submit();
|
||||
expect(await relier.isPro()).toBe(true);
|
||||
|
||||
// check conversion funnel metrics
|
||||
const expectedEventTypes = [
|
||||
'amplitude.subPaySetup.view',
|
||||
'amplitude.subPaySetup.engage',
|
||||
'amplitude.subPaySetup.submit',
|
||||
'amplitude.subPaySetup.fail',
|
||||
'amplitude.subPaySetup.submit',
|
||||
'amplitude.subPaySetup.success',
|
||||
];
|
||||
const actualEventTypes = metricsObserver.rawEvents.map((event) => {
|
||||
return event.type;
|
||||
test.beforeEach(({ pages: { subscribe } }) => {
|
||||
test.slow();
|
||||
metricsObserver = new MetricsObserver(subscribe);
|
||||
metricsObserver.startTracking();
|
||||
});
|
||||
expect(actualEventTypes).toMatchObject(expectedEventTypes);
|
||||
});
|
||||
|
||||
test('subscribe with paypal and login to product', async ({
|
||||
pages: { relier, login, subscribe },
|
||||
}, { project }) => {
|
||||
test.skip(
|
||||
project.name === 'production',
|
||||
'no real payment method available in prod'
|
||||
);
|
||||
await relier.goto();
|
||||
await relier.clickSubscribe();
|
||||
await subscribe.setConfirmPaymentCheckbox();
|
||||
await subscribe.setPayPalInfo();
|
||||
await subscribe.submit();
|
||||
await relier.goto();
|
||||
await relier.clickEmailFirst();
|
||||
await login.submit();
|
||||
expect(await relier.isPro()).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
test.describe('Flow, acquisition and new user checkout funnel metrics', () => {
|
||||
let metricsObserver: MetricsObserver;
|
||||
|
||||
test.beforeEach(({ pages: { subscribe } }) => {
|
||||
test.slow();
|
||||
metricsObserver = new MetricsObserver(subscribe);
|
||||
metricsObserver.startTracking();
|
||||
});
|
||||
|
||||
test.describe('severity-2', () => {
|
||||
test('Metrics disabled: existing user checkout URL to not have flow params', async ({
|
||||
pages: { settings, relier, page },
|
||||
test('subscribe with credit card and login to product', async ({
|
||||
pages: { relier, login, subscribe },
|
||||
}, { project }) => {
|
||||
test.skip(
|
||||
project.name === 'production',
|
||||
'test plan not yet available in prod'
|
||||
'no real payment method available in prod'
|
||||
);
|
||||
// Go to settings page and verify the Data Collection toggle switch is visible
|
||||
await settings.goto();
|
||||
expect(await settings.dataCollection.isToggleSwitch()).toBe(true);
|
||||
|
||||
// Toggle swtich, verify the alert bar appears and its status
|
||||
await settings.dataCollection.toggleShareData('off');
|
||||
expect(await settings.alertBarText()).toContain('Opt out successful.');
|
||||
expect(await settings.dataCollection.getToggleStatus()).toBe('false');
|
||||
|
||||
// Subscribe to plan and verify URL does not include flow parameter
|
||||
await relier.goto();
|
||||
await relier.clickSubscribe6Month();
|
||||
expect(page.url()).not.toContain('&flow_begin_time=');
|
||||
await relier.clickSubscribe();
|
||||
await subscribe.setConfirmPaymentCheckbox();
|
||||
await subscribe.setFullName();
|
||||
await subscribe.setCreditCardInfo();
|
||||
await subscribe.clickPayNow();
|
||||
await subscribe.submit();
|
||||
await relier.goto();
|
||||
await relier.clickEmailFirst();
|
||||
await login.submit();
|
||||
expect(await relier.isPro()).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
test.describe('severity-3', () => {
|
||||
test('Existing user checkout URL to have flow params', async ({
|
||||
pages: { settings, relier, page },
|
||||
test('subscribe with credit card after initial failed subscription & verify existing user checkout funnel metrics', async ({
|
||||
pages: { relier, login, subscribe },
|
||||
}, { project }) => {
|
||||
test.skip(
|
||||
project.name === 'production',
|
||||
'test plan not yet available in prod'
|
||||
'no real payment method available in prod'
|
||||
);
|
||||
// Go to settings page and verify the Data Collection toggle switch is visible
|
||||
await settings.goto();
|
||||
expect(await settings.dataCollection.isToggleSwitch()).toBe(true);
|
||||
|
||||
// Toggle swtich and verify its status
|
||||
await settings.dataCollection.toggleShareData('on');
|
||||
expect(await settings.dataCollection.getToggleStatus()).toBe('true');
|
||||
|
||||
// Subscribe to plan and verify URL does not include flow parameter
|
||||
await relier.goto();
|
||||
await relier.clickSubscribe6Month();
|
||||
expect(page.url()).toContain('&flow_begin_time=');
|
||||
});
|
||||
|
||||
test('New user checkout URL to have flow params', async ({
|
||||
pages: { settings, relier, page },
|
||||
}, { project }) => {
|
||||
test.skip(
|
||||
project.name === 'production',
|
||||
'test plan not yet available in prod'
|
||||
);
|
||||
await settings.goto();
|
||||
await settings.signOut();
|
||||
await relier.goto();
|
||||
await relier.clickSubscribe6Month();
|
||||
expect(page.url()).toContain('&flow_begin_time=');
|
||||
});
|
||||
|
||||
test('New user checkout URL to have flow params with cache cleared', async ({
|
||||
pages: { settings, login, relier, page },
|
||||
}, { project }) => {
|
||||
test.skip(
|
||||
project.name === 'production',
|
||||
'test plan not yet available in prod'
|
||||
);
|
||||
await settings.goto();
|
||||
await settings.signOut();
|
||||
await login.clearCache();
|
||||
await relier.goto();
|
||||
await relier.clickSubscribe6Month();
|
||||
expect(page.url()).toContain('&flow_begin_time=');
|
||||
});
|
||||
|
||||
test('New user checkout URL to have RP-provided flow params, acquisition params & verify funnel metrics', async ({
|
||||
pages: { settings, relier, page, subscribe },
|
||||
}, { project }) => {
|
||||
test.skip(
|
||||
project.name === 'production',
|
||||
'test plan not yet available in prod'
|
||||
);
|
||||
await settings.goto();
|
||||
await settings.signOut();
|
||||
await relier.goto();
|
||||
|
||||
const subscribeUrl = await relier.getUrl();
|
||||
if (!subscribeUrl) {
|
||||
fail('Subscribe button has no href.');
|
||||
}
|
||||
const rpSearchParamsBefore = relier.getRpSearchParams(subscribeUrl);
|
||||
const rpFlowParamsBefore = relier.getRpFlowParams(rpSearchParamsBefore);
|
||||
const acquisitionParamsBefore =
|
||||
relier.getRpAcquisitionParams(rpSearchParamsBefore);
|
||||
|
||||
// check flow metrics
|
||||
await relier.clickSubscribeRPFlowMetrics();
|
||||
const rpSearchParamsAfter = relier.getRpSearchParams(page.url());
|
||||
const rpFlowParamsAfter = relier.getRpFlowParams(rpSearchParamsAfter);
|
||||
expect(rpFlowParamsAfter).toStrictEqual(rpFlowParamsBefore);
|
||||
|
||||
// subscribe, failing first then succeeding
|
||||
await subscribe.setEmailAndConfirmNewUser();
|
||||
await relier.clickSubscribe();
|
||||
await subscribe.setConfirmPaymentCheckbox();
|
||||
await subscribe.setFullName();
|
||||
await subscribe.setFailedCreditCardInfo();
|
||||
|
@ -208,11 +54,10 @@ test.describe('Flow, acquisition and new user checkout funnel metrics', () => {
|
|||
await subscribe.setCreditCardInfo();
|
||||
await subscribe.clickPayNow();
|
||||
await subscribe.submit();
|
||||
|
||||
// check acquisition metrics
|
||||
const acquisitionParamsAfter =
|
||||
metricsObserver.getAcquisitionParamsFromEvents();
|
||||
expect(acquisitionParamsAfter).toStrictEqual(acquisitionParamsBefore);
|
||||
await relier.goto();
|
||||
await relier.clickEmailFirst();
|
||||
await login.submit();
|
||||
expect(await relier.isPro()).toBe(true);
|
||||
|
||||
// check conversion funnel metrics
|
||||
const expectedEventTypes = [
|
||||
|
@ -228,5 +73,166 @@ test.describe('Flow, acquisition and new user checkout funnel metrics', () => {
|
|||
});
|
||||
expect(actualEventTypes).toMatchObject(expectedEventTypes);
|
||||
});
|
||||
|
||||
test('subscribe with paypal and login to product', async ({
|
||||
pages: { relier, login, subscribe },
|
||||
}, { project }) => {
|
||||
test.skip(
|
||||
project.name === 'production',
|
||||
'no real payment method available in prod'
|
||||
);
|
||||
await relier.goto();
|
||||
await relier.clickSubscribe();
|
||||
await subscribe.setConfirmPaymentCheckbox();
|
||||
await subscribe.setPayPalInfo();
|
||||
await subscribe.submit();
|
||||
await relier.goto();
|
||||
await relier.clickEmailFirst();
|
||||
await login.submit();
|
||||
expect(await relier.isPro()).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
test.describe('Flow, acquisition and new user checkout funnel metrics', () => {
|
||||
let metricsObserver: MetricsObserver;
|
||||
|
||||
test.beforeEach(({ pages: { subscribe } }) => {
|
||||
test.slow();
|
||||
metricsObserver = new MetricsObserver(subscribe);
|
||||
metricsObserver.startTracking();
|
||||
});
|
||||
|
||||
test.describe('severity-2', () => {
|
||||
test('Metrics disabled: existing user checkout URL to not have flow params', async ({
|
||||
pages: { settings, relier, page },
|
||||
}, { project }) => {
|
||||
test.skip(
|
||||
project.name === 'production',
|
||||
'test plan not yet available in prod'
|
||||
);
|
||||
// Go to settings page and verify the Data Collection toggle switch is visible
|
||||
await settings.goto();
|
||||
expect(await settings.dataCollection.isToggleSwitch()).toBe(true);
|
||||
|
||||
// Toggle swtich, verify the alert bar appears and its status
|
||||
await settings.dataCollection.toggleShareData('off');
|
||||
expect(await settings.alertBarText()).toContain('Opt out successful.');
|
||||
expect(await settings.dataCollection.getToggleStatus()).toBe('false');
|
||||
|
||||
// Subscribe to plan and verify URL does not include flow parameter
|
||||
await relier.goto();
|
||||
await relier.clickSubscribe6Month();
|
||||
expect(page.url()).not.toContain('&flow_begin_time=');
|
||||
});
|
||||
});
|
||||
|
||||
test.describe('severity-2', () => {
|
||||
test('Existing user checkout URL to have flow params', async ({
|
||||
pages: { settings, relier, page },
|
||||
}, { project }) => {
|
||||
test.skip(
|
||||
project.name === 'production',
|
||||
'test plan not yet available in prod'
|
||||
);
|
||||
// Go to settings page and verify the Data Collection toggle switch is visible
|
||||
await settings.goto();
|
||||
expect(await settings.dataCollection.isToggleSwitch()).toBe(true);
|
||||
|
||||
// Toggle swtich and verify its status
|
||||
await settings.dataCollection.toggleShareData('on');
|
||||
expect(await settings.dataCollection.getToggleStatus()).toBe('true');
|
||||
|
||||
// Subscribe to plan and verify URL does not include flow parameter
|
||||
await relier.goto();
|
||||
await relier.clickSubscribe6Month();
|
||||
expect(page.url()).toContain('&flow_begin_time=');
|
||||
});
|
||||
|
||||
test('New user checkout URL to have flow params', async ({
|
||||
pages: { settings, relier, page },
|
||||
}, { project }) => {
|
||||
test.skip(
|
||||
project.name === 'production',
|
||||
'test plan not yet available in prod'
|
||||
);
|
||||
await settings.goto();
|
||||
await settings.signOut();
|
||||
await relier.goto();
|
||||
await relier.clickSubscribe6Month();
|
||||
expect(page.url()).toContain('&flow_begin_time=');
|
||||
});
|
||||
|
||||
test('New user checkout URL to have flow params with cache cleared', async ({
|
||||
pages: { settings, login, relier, page },
|
||||
}, { project }) => {
|
||||
test.skip(
|
||||
project.name === 'production',
|
||||
'test plan not yet available in prod'
|
||||
);
|
||||
await settings.goto();
|
||||
await settings.signOut();
|
||||
await login.clearCache();
|
||||
await relier.goto();
|
||||
await relier.clickSubscribe6Month();
|
||||
expect(page.url()).toContain('&flow_begin_time=');
|
||||
});
|
||||
|
||||
test('New user checkout URL to have RP-provided flow params, acquisition params & verify funnel metrics', async ({
|
||||
pages: { settings, relier, page, subscribe },
|
||||
}, { project }) => {
|
||||
test.skip(
|
||||
project.name === 'production',
|
||||
'test plan not yet available in prod'
|
||||
);
|
||||
await settings.goto();
|
||||
await settings.signOut();
|
||||
await relier.goto();
|
||||
|
||||
const subscribeUrl = await relier.getUrl();
|
||||
if (!subscribeUrl) {
|
||||
fail('Subscribe button has no href.');
|
||||
}
|
||||
const rpSearchParamsBefore = relier.getRpSearchParams(subscribeUrl);
|
||||
const rpFlowParamsBefore = relier.getRpFlowParams(rpSearchParamsBefore);
|
||||
const acquisitionParamsBefore =
|
||||
relier.getRpAcquisitionParams(rpSearchParamsBefore);
|
||||
|
||||
// check flow metrics
|
||||
await relier.clickSubscribeRPFlowMetrics();
|
||||
const rpSearchParamsAfter = relier.getRpSearchParams(page.url());
|
||||
const rpFlowParamsAfter = relier.getRpFlowParams(rpSearchParamsAfter);
|
||||
expect(rpFlowParamsAfter).toStrictEqual(rpFlowParamsBefore);
|
||||
|
||||
// subscribe, failing first then succeeding
|
||||
await subscribe.setEmailAndConfirmNewUser();
|
||||
await subscribe.setConfirmPaymentCheckbox();
|
||||
await subscribe.setFullName();
|
||||
await subscribe.setFailedCreditCardInfo();
|
||||
await subscribe.clickPayNow();
|
||||
await subscribe.clickTryAgain();
|
||||
await subscribe.setCreditCardInfo();
|
||||
await subscribe.clickPayNow();
|
||||
await subscribe.submit();
|
||||
|
||||
// check acquisition metrics
|
||||
const acquisitionParamsAfter =
|
||||
metricsObserver.getAcquisitionParamsFromEvents();
|
||||
expect(acquisitionParamsAfter).toStrictEqual(acquisitionParamsBefore);
|
||||
|
||||
// check conversion funnel metrics
|
||||
const expectedEventTypes = [
|
||||
'amplitude.subPaySetup.view',
|
||||
'amplitude.subPaySetup.engage',
|
||||
'amplitude.subPaySetup.submit',
|
||||
'amplitude.subPaySetup.fail',
|
||||
'amplitude.subPaySetup.submit',
|
||||
'amplitude.subPaySetup.success',
|
||||
];
|
||||
const actualEventTypes = metricsObserver.rawEvents.map((event) => {
|
||||
return event.type;
|
||||
});
|
||||
expect(actualEventTypes).toMatchObject(expectedEventTypes);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -1,91 +1,99 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
import { test, expect } from '../../lib/fixtures/standard';
|
||||
|
||||
test.describe('support form without valid session', () => {
|
||||
test('go to support form, redirects to index', async ({
|
||||
page,
|
||||
target,
|
||||
pages: { login },
|
||||
}) => {
|
||||
await login.clearCache();
|
||||
await page.goto(`${target.contentServerUrl}/support`, {
|
||||
waitUntil: 'load',
|
||||
test.describe('severity-1 #smoke', () => {
|
||||
test.describe('support form without valid session', () => {
|
||||
test('go to support form, redirects to index', async ({
|
||||
page,
|
||||
target,
|
||||
pages: { login },
|
||||
}) => {
|
||||
await login.clearCache();
|
||||
await page.goto(`${target.contentServerUrl}/support`, {
|
||||
waitUntil: 'load',
|
||||
});
|
||||
await login.waitForEmailHeader();
|
||||
});
|
||||
await login.waitForEmailHeader();
|
||||
});
|
||||
});
|
||||
|
||||
test.describe('support form without active subscriptions', () => {
|
||||
test('go to support form, redirects to subscription management, then back to settings', async ({
|
||||
page,
|
||||
target,
|
||||
pages: { login },
|
||||
}) => {
|
||||
test.slow();
|
||||
await page.goto(`${target.contentServerUrl}/support`, {
|
||||
waitUntil: 'load',
|
||||
test.describe('support form without active subscriptions', () => {
|
||||
test('go to support form, redirects to subscription management, then back to settings', async ({
|
||||
page,
|
||||
target,
|
||||
pages: { login },
|
||||
}) => {
|
||||
test.slow();
|
||||
await page.goto(`${target.contentServerUrl}/support`, {
|
||||
waitUntil: 'load',
|
||||
});
|
||||
await page.waitForURL(/settings/);
|
||||
expect(await login.isUserLoggedIn()).toBe(true);
|
||||
});
|
||||
await page.waitForURL(/settings/);
|
||||
expect(await login.isUserLoggedIn()).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
test.describe('support form with active subscriptions', () => {
|
||||
test.beforeEach(() => {
|
||||
test.slow();
|
||||
});
|
||||
test.describe('severity-2 #smoke', () => {
|
||||
test.describe('support form with active subscriptions', () => {
|
||||
test.beforeEach(() => {
|
||||
test.slow();
|
||||
});
|
||||
|
||||
test('go to support form, submits the form', async ({
|
||||
pages: { login, relier, subscribe, settings, subscriptionManagement },
|
||||
}, { project }) => {
|
||||
test.skip(
|
||||
project.name === 'production',
|
||||
'no real payment method available in prod'
|
||||
);
|
||||
await relier.goto();
|
||||
await relier.clickSubscribe();
|
||||
await subscribe.setConfirmPaymentCheckbox();
|
||||
await subscribe.setFullName();
|
||||
await subscribe.setCreditCardInfo();
|
||||
await subscribe.clickPayNow();
|
||||
await subscribe.submit();
|
||||
test('go to support form, submits the form', async ({
|
||||
pages: { login, relier, subscribe, settings, subscriptionManagement },
|
||||
}, { project }) => {
|
||||
test.skip(
|
||||
project.name === 'production',
|
||||
'no real payment method available in prod'
|
||||
);
|
||||
await relier.goto();
|
||||
await relier.clickSubscribe();
|
||||
await subscribe.setConfirmPaymentCheckbox();
|
||||
await subscribe.setFullName();
|
||||
await subscribe.setCreditCardInfo();
|
||||
await subscribe.clickPayNow();
|
||||
await subscribe.submit();
|
||||
|
||||
//Login to FxA account
|
||||
await login.goto();
|
||||
await login.clickSignIn();
|
||||
const subscriptionPage = await settings.clickPaidSubscriptions();
|
||||
subscriptionManagement.page = subscriptionPage;
|
||||
await subscriptionManagement.fillSupportForm();
|
||||
//Login to FxA account
|
||||
await login.goto();
|
||||
await login.clickSignIn();
|
||||
const subscriptionPage = await settings.clickPaidSubscriptions();
|
||||
subscriptionManagement.page = subscriptionPage;
|
||||
await subscriptionManagement.fillSupportForm();
|
||||
|
||||
//Since we don't have proper Zendesk config in CircleCI, the form cannot be successfully submitted
|
||||
//await subscriptionManagement.submitSupportForm();
|
||||
//expect(await subscriptionManagement.subscriptionManagementHeader()).toBe(true);
|
||||
});
|
||||
//Since we don't have proper Zendesk config in CircleCI, the form cannot be successfully submitted
|
||||
//await subscriptionManagement.submitSupportForm();
|
||||
//expect(await subscriptionManagement.subscriptionManagementHeader()).toBe(true);
|
||||
});
|
||||
|
||||
test('go to support form, cancel, redirects to subscription management', async ({
|
||||
page,
|
||||
pages: { login, relier, subscribe, settings, subscriptionManagement },
|
||||
}, { project }) => {
|
||||
test.skip(
|
||||
project.name === 'production',
|
||||
'no real payment method available in prod'
|
||||
);
|
||||
await relier.goto();
|
||||
await relier.clickSubscribe();
|
||||
await subscribe.setConfirmPaymentCheckbox();
|
||||
await subscribe.setFullName();
|
||||
await subscribe.setCreditCardInfo();
|
||||
await subscribe.clickPayNow();
|
||||
await subscribe.submit();
|
||||
test('go to support form, cancel, redirects to subscription management', async ({
|
||||
page,
|
||||
pages: { login, relier, subscribe, settings, subscriptionManagement },
|
||||
}, { project }) => {
|
||||
test.skip(
|
||||
project.name === 'production',
|
||||
'no real payment method available in prod'
|
||||
);
|
||||
await relier.goto();
|
||||
await relier.clickSubscribe();
|
||||
await subscribe.setConfirmPaymentCheckbox();
|
||||
await subscribe.setFullName();
|
||||
await subscribe.setCreditCardInfo();
|
||||
await subscribe.clickPayNow();
|
||||
await subscribe.submit();
|
||||
|
||||
//Login to FxA account
|
||||
await login.goto();
|
||||
await login.clickSignIn();
|
||||
const subscriptionPage = await settings.clickPaidSubscriptions();
|
||||
subscriptionManagement.page = subscriptionPage;
|
||||
await subscriptionManagement.fillSupportForm();
|
||||
await subscriptionManagement.cancelSupportForm();
|
||||
//Login to FxA account
|
||||
await login.goto();
|
||||
await login.clickSignIn();
|
||||
const subscriptionPage = await settings.clickPaidSubscriptions();
|
||||
subscriptionManagement.page = subscriptionPage;
|
||||
await subscriptionManagement.fillSupportForm();
|
||||
await subscriptionManagement.cancelSupportForm();
|
||||
|
||||
//Verify it redirects back to the subscription management page
|
||||
expect(await subscriptionManagement.subscriptiontHeader()).toBe(true);
|
||||
//Verify it redirects back to the subscription management page
|
||||
expect(await subscriptionManagement.subscriptiontHeader()).toBe(true);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -14,250 +14,252 @@ let otherEmail;
|
|||
|
||||
test.describe.configure({ mode: 'parallel' });
|
||||
|
||||
test.describe('Firefox desktop user info handshake', () => {
|
||||
test.beforeEach(async ({ target, page }) => {
|
||||
test.slow();
|
||||
syncBrowserPages = await newPagesForSync(target);
|
||||
const { login } = syncBrowserPages;
|
||||
browserSignedInEmail = login.createEmail();
|
||||
await target.auth.signUp(browserSignedInEmail, password, {
|
||||
lang: 'en',
|
||||
preVerified: 'true',
|
||||
test.describe('severity-2 #smoke', () => {
|
||||
test.describe('Firefox desktop user info handshake', () => {
|
||||
test.beforeEach(async ({ target, page }) => {
|
||||
test.slow();
|
||||
syncBrowserPages = await newPagesForSync(target);
|
||||
const { login } = syncBrowserPages;
|
||||
browserSignedInEmail = login.createEmail();
|
||||
await target.auth.signUp(browserSignedInEmail, password, {
|
||||
lang: 'en',
|
||||
preVerified: 'true',
|
||||
});
|
||||
otherEmail = login.createEmail();
|
||||
await target.auth.signUp(otherEmail, password, {
|
||||
lang: 'en',
|
||||
preVerified: 'true',
|
||||
});
|
||||
});
|
||||
otherEmail = login.createEmail();
|
||||
await target.auth.signUp(otherEmail, password, {
|
||||
lang: 'en',
|
||||
preVerified: 'true',
|
||||
});
|
||||
});
|
||||
|
||||
test.afterEach(async ({ target }) => {
|
||||
await syncBrowserPages.browser?.close();
|
||||
const emails = [browserSignedInEmail, otherEmail];
|
||||
for (const email of emails) {
|
||||
if (email) {
|
||||
// Cleanup any accounts created during the test
|
||||
try {
|
||||
await target.auth.accountDestroy(email, password);
|
||||
} catch (e) {
|
||||
// Handle the error here
|
||||
console.error('An error occurred during account cleanup:', e);
|
||||
// Optionally, rethrow the error to propagate it further
|
||||
throw e;
|
||||
test.afterEach(async ({ target }) => {
|
||||
await syncBrowserPages.browser?.close();
|
||||
const emails = [browserSignedInEmail, otherEmail];
|
||||
for (const email of emails) {
|
||||
if (email) {
|
||||
// Cleanup any accounts created during the test
|
||||
try {
|
||||
await target.auth.accountDestroy(email, password);
|
||||
} catch (e) {
|
||||
// Handle the error here
|
||||
console.error('An error occurred during account cleanup:', e);
|
||||
// Optionally, rethrow the error to propagate it further
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
test('Non-Sync - user signed into browser, user signed in locally', async ({
|
||||
target,
|
||||
}) => {
|
||||
const { login, page } = syncBrowserPages;
|
||||
const query = new URLSearchParams({
|
||||
forceUA: uaStrings['desktop_firefox_71'],
|
||||
});
|
||||
const eventDetailStatus = createCustomEventDetail(
|
||||
FirefoxCommand.FxAStatus,
|
||||
{
|
||||
signedInUser: null,
|
||||
}
|
||||
);
|
||||
await page.goto(
|
||||
`${target.contentServerUrl}?automatedBrowser=true&${query.toString()}`
|
||||
);
|
||||
await login.respondToWebChannelMessage(eventDetailStatus);
|
||||
await login.checkWebChannelMessage('fxaccounts:fxa_status');
|
||||
await login.fillOutEmailFirstSignIn(otherEmail, password);
|
||||
expect(await login.isUserLoggedIn()).toBe(true);
|
||||
|
||||
// Then, sign in the user again, synthesizing the user having signed
|
||||
// into Sync after the initial sign in.
|
||||
const eventDetailStatusSignIn = createCustomEventDetail(
|
||||
FirefoxCommand.FxAStatus,
|
||||
{
|
||||
signedInUser: browserSignedInEmail,
|
||||
}
|
||||
);
|
||||
await page.goto(
|
||||
`${target.contentServerUrl}?automatedBrowser=true&${query.toString()}`
|
||||
);
|
||||
await login.respondToWebChannelMessage(eventDetailStatusSignIn);
|
||||
await login.checkWebChannelMessage('fxaccounts:fxa_status');
|
||||
test('Non-Sync - user signed into browser, user signed in locally', async ({
|
||||
target,
|
||||
}) => {
|
||||
const { login, page } = syncBrowserPages;
|
||||
const query = new URLSearchParams({
|
||||
forceUA: uaStrings['desktop_firefox_71'],
|
||||
});
|
||||
const eventDetailStatus = createCustomEventDetail(
|
||||
FirefoxCommand.FxAStatus,
|
||||
{
|
||||
signedInUser: null,
|
||||
}
|
||||
);
|
||||
await page.goto(
|
||||
`${target.contentServerUrl}?automatedBrowser=true&${query.toString()}`
|
||||
);
|
||||
await login.respondToWebChannelMessage(eventDetailStatus);
|
||||
await login.checkWebChannelMessage('fxaccounts:fxa_status');
|
||||
await login.fillOutEmailFirstSignIn(otherEmail, password);
|
||||
expect(await login.isUserLoggedIn()).toBe(true);
|
||||
|
||||
expect(await login.getPrefilledEmail()).toContain(otherEmail);
|
||||
await login.clickSignIn();
|
||||
expect(await login.isUserLoggedIn()).toBe(true);
|
||||
});
|
||||
// Then, sign in the user again, synthesizing the user having signed
|
||||
// into Sync after the initial sign in.
|
||||
const eventDetailStatusSignIn = createCustomEventDetail(
|
||||
FirefoxCommand.FxAStatus,
|
||||
{
|
||||
signedInUser: browserSignedInEmail,
|
||||
}
|
||||
);
|
||||
await page.goto(
|
||||
`${target.contentServerUrl}?automatedBrowser=true&${query.toString()}`
|
||||
);
|
||||
await login.respondToWebChannelMessage(eventDetailStatusSignIn);
|
||||
await login.checkWebChannelMessage('fxaccounts:fxa_status');
|
||||
|
||||
test('Sync - no user signed into browser, no user signed in locally', async ({
|
||||
target,
|
||||
}) => {
|
||||
const { login, page } = syncBrowserPages;
|
||||
const query = new URLSearchParams({
|
||||
forceUA: uaStrings['desktop_firefox_71'],
|
||||
expect(await login.getPrefilledEmail()).toContain(otherEmail);
|
||||
await login.clickSignIn();
|
||||
expect(await login.isUserLoggedIn()).toBe(true);
|
||||
});
|
||||
await page.goto(
|
||||
`${
|
||||
target.contentServerUrl
|
||||
}?context=fx_desktop_v3&service=sync&${query.toString()}`
|
||||
);
|
||||
await login.waitForEmailHeader();
|
||||
expect(await login.getEmailInput()).toContain('');
|
||||
});
|
||||
|
||||
test('Sync - no user signed into browser, user signed in locally', async ({
|
||||
target,
|
||||
}) => {
|
||||
const { login, page } = syncBrowserPages;
|
||||
const query = new URLSearchParams({
|
||||
forceUA: uaStrings['desktop_firefox_71'],
|
||||
test('Sync - no user signed into browser, no user signed in locally', async ({
|
||||
target,
|
||||
}) => {
|
||||
const { login, page } = syncBrowserPages;
|
||||
const query = new URLSearchParams({
|
||||
forceUA: uaStrings['desktop_firefox_71'],
|
||||
});
|
||||
await page.goto(
|
||||
`${
|
||||
target.contentServerUrl
|
||||
}?context=fx_desktop_v3&service=sync&${query.toString()}`
|
||||
);
|
||||
await login.waitForEmailHeader();
|
||||
expect(await login.getEmailInput()).toContain('');
|
||||
});
|
||||
await page.goto(
|
||||
`${target.contentServerUrl}?automatedBrowser=true&${query.toString()}`
|
||||
);
|
||||
await login.fillOutEmailFirstSignIn(otherEmail, password);
|
||||
expect(await login.isUserLoggedIn()).toBe(true);
|
||||
await page.goto(
|
||||
`${
|
||||
target.contentServerUrl
|
||||
}?context=fx_desktop_v3&service=sync&automatedBrowser=true&${query.toString()}`
|
||||
);
|
||||
expect(await login.getPrefilledEmail()).toContain(otherEmail);
|
||||
});
|
||||
|
||||
test('Non-Sync - no user signed into browser, no user signed in locally', async ({
|
||||
target,
|
||||
}) => {
|
||||
const { login, page } = syncBrowserPages;
|
||||
const query = new URLSearchParams({
|
||||
forceUA: uaStrings['desktop_firefox_71'],
|
||||
test('Sync - no user signed into browser, user signed in locally', async ({
|
||||
target,
|
||||
}) => {
|
||||
const { login, page } = syncBrowserPages;
|
||||
const query = new URLSearchParams({
|
||||
forceUA: uaStrings['desktop_firefox_71'],
|
||||
});
|
||||
await page.goto(
|
||||
`${target.contentServerUrl}?automatedBrowser=true&${query.toString()}`
|
||||
);
|
||||
await login.fillOutEmailFirstSignIn(otherEmail, password);
|
||||
expect(await login.isUserLoggedIn()).toBe(true);
|
||||
await page.goto(
|
||||
`${
|
||||
target.contentServerUrl
|
||||
}?context=fx_desktop_v3&service=sync&automatedBrowser=true&${query.toString()}`
|
||||
);
|
||||
expect(await login.getPrefilledEmail()).toContain(otherEmail);
|
||||
});
|
||||
const eventDetailStatus = createCustomEventDetail(
|
||||
FirefoxCommand.FxAStatus,
|
||||
{
|
||||
signedInUser: null,
|
||||
}
|
||||
);
|
||||
await page.goto(
|
||||
`${target.contentServerUrl}?automatedBrowser=true&${query.toString()}`
|
||||
);
|
||||
await login.respondToWebChannelMessage(eventDetailStatus);
|
||||
await login.checkWebChannelMessage('fxaccounts:fxa_status');
|
||||
expect(await login.getEmailInput()).toContain('');
|
||||
});
|
||||
|
||||
test('Sync force_auth page - user signed into browser is different to requested user', async ({
|
||||
target,
|
||||
}) => {
|
||||
const { login, page } = syncBrowserPages;
|
||||
const query = new URLSearchParams({
|
||||
forceUA: uaStrings['desktop_firefox_71'],
|
||||
email: otherEmail,
|
||||
test('Non-Sync - no user signed into browser, no user signed in locally', async ({
|
||||
target,
|
||||
}) => {
|
||||
const { login, page } = syncBrowserPages;
|
||||
const query = new URLSearchParams({
|
||||
forceUA: uaStrings['desktop_firefox_71'],
|
||||
});
|
||||
const eventDetailStatus = createCustomEventDetail(
|
||||
FirefoxCommand.FxAStatus,
|
||||
{
|
||||
signedInUser: null,
|
||||
}
|
||||
);
|
||||
await page.goto(
|
||||
`${target.contentServerUrl}?automatedBrowser=true&${query.toString()}`
|
||||
);
|
||||
await login.respondToWebChannelMessage(eventDetailStatus);
|
||||
await login.checkWebChannelMessage('fxaccounts:fxa_status');
|
||||
expect(await login.getEmailInput()).toContain('');
|
||||
});
|
||||
const eventDetailStatus = createCustomEventDetail(
|
||||
FirefoxCommand.FxAStatus,
|
||||
{
|
||||
signedInUser: browserSignedInEmail,
|
||||
}
|
||||
);
|
||||
await page.goto(
|
||||
`${
|
||||
target.contentServerUrl
|
||||
}?force_auth&automatedBrowser=true&context=fx_desktop_v3&service=sync&${query.toString()}`
|
||||
);
|
||||
await login.respondToWebChannelMessage(eventDetailStatus);
|
||||
await login.checkWebChannelMessage('fxaccounts:fxa_status');
|
||||
expect(await login.getPrefilledEmail()).toContain(otherEmail);
|
||||
});
|
||||
|
||||
test('Non-Sync force_auth page - user signed into browser is different to requested user', async ({
|
||||
target,
|
||||
}) => {
|
||||
const { login, page } = syncBrowserPages;
|
||||
const query = new URLSearchParams({
|
||||
forceUA: uaStrings['desktop_firefox_71'],
|
||||
email: otherEmail,
|
||||
test('Sync force_auth page - user signed into browser is different to requested user', async ({
|
||||
target,
|
||||
}) => {
|
||||
const { login, page } = syncBrowserPages;
|
||||
const query = new URLSearchParams({
|
||||
forceUA: uaStrings['desktop_firefox_71'],
|
||||
email: otherEmail,
|
||||
});
|
||||
const eventDetailStatus = createCustomEventDetail(
|
||||
FirefoxCommand.FxAStatus,
|
||||
{
|
||||
signedInUser: browserSignedInEmail,
|
||||
}
|
||||
);
|
||||
await page.goto(
|
||||
`${
|
||||
target.contentServerUrl
|
||||
}?force_auth&automatedBrowser=true&context=fx_desktop_v3&service=sync&${query.toString()}`
|
||||
);
|
||||
await login.respondToWebChannelMessage(eventDetailStatus);
|
||||
await login.checkWebChannelMessage('fxaccounts:fxa_status');
|
||||
expect(await login.getPrefilledEmail()).toContain(otherEmail);
|
||||
});
|
||||
const eventDetailStatus = createCustomEventDetail(
|
||||
FirefoxCommand.FxAStatus,
|
||||
{
|
||||
signedInUser: browserSignedInEmail,
|
||||
}
|
||||
);
|
||||
await page.goto(
|
||||
`${
|
||||
target.contentServerUrl
|
||||
}?force_auth&automatedBrowser=true&${query.toString()}`
|
||||
);
|
||||
await login.respondToWebChannelMessage(eventDetailStatus);
|
||||
await login.checkWebChannelMessage('fxaccounts:fxa_status');
|
||||
expect(await login.getPrefilledEmail()).toContain(otherEmail);
|
||||
});
|
||||
|
||||
test('Sync - user signed into browser, no user signed in locally', async ({
|
||||
target,
|
||||
}) => {
|
||||
const { login, page } = syncBrowserPages;
|
||||
const query = new URLSearchParams({
|
||||
forceUA: uaStrings['desktop_firefox_71'],
|
||||
email: browserSignedInEmail,
|
||||
test('Non-Sync force_auth page - user signed into browser is different to requested user', async ({
|
||||
target,
|
||||
}) => {
|
||||
const { login, page } = syncBrowserPages;
|
||||
const query = new URLSearchParams({
|
||||
forceUA: uaStrings['desktop_firefox_71'],
|
||||
email: otherEmail,
|
||||
});
|
||||
const eventDetailStatus = createCustomEventDetail(
|
||||
FirefoxCommand.FxAStatus,
|
||||
{
|
||||
signedInUser: browserSignedInEmail,
|
||||
}
|
||||
);
|
||||
await page.goto(
|
||||
`${
|
||||
target.contentServerUrl
|
||||
}?force_auth&automatedBrowser=true&${query.toString()}`
|
||||
);
|
||||
await login.respondToWebChannelMessage(eventDetailStatus);
|
||||
await login.checkWebChannelMessage('fxaccounts:fxa_status');
|
||||
expect(await login.getPrefilledEmail()).toContain(otherEmail);
|
||||
});
|
||||
const eventDetailStatus = createCustomEventDetail(
|
||||
FirefoxCommand.FxAStatus,
|
||||
{
|
||||
signedInUser: browserSignedInEmail,
|
||||
}
|
||||
);
|
||||
await page.goto(
|
||||
`${
|
||||
target.contentServerUrl
|
||||
}?context=fx_desktop_v3&service=sync&automatedBrowser=true&${query.toString()}`
|
||||
);
|
||||
await login.respondToWebChannelMessage(eventDetailStatus);
|
||||
await login.checkWebChannelMessage('fxaccounts:fxa_status');
|
||||
expect(await login.getPrefilledEmail()).toContain(browserSignedInEmail);
|
||||
});
|
||||
|
||||
test('Non-Sync - user signed into browser, no user signed in locally', async ({
|
||||
target,
|
||||
}) => {
|
||||
const { login, page } = syncBrowserPages;
|
||||
const query = new URLSearchParams({
|
||||
forceUA: uaStrings['desktop_firefox_71'],
|
||||
email: browserSignedInEmail,
|
||||
test('Sync - user signed into browser, no user signed in locally', async ({
|
||||
target,
|
||||
}) => {
|
||||
const { login, page } = syncBrowserPages;
|
||||
const query = new URLSearchParams({
|
||||
forceUA: uaStrings['desktop_firefox_71'],
|
||||
email: browserSignedInEmail,
|
||||
});
|
||||
const eventDetailStatus = createCustomEventDetail(
|
||||
FirefoxCommand.FxAStatus,
|
||||
{
|
||||
signedInUser: browserSignedInEmail,
|
||||
}
|
||||
);
|
||||
await page.goto(
|
||||
`${
|
||||
target.contentServerUrl
|
||||
}?context=fx_desktop_v3&service=sync&automatedBrowser=true&${query.toString()}`
|
||||
);
|
||||
await login.respondToWebChannelMessage(eventDetailStatus);
|
||||
await login.checkWebChannelMessage('fxaccounts:fxa_status');
|
||||
expect(await login.getPrefilledEmail()).toContain(browserSignedInEmail);
|
||||
});
|
||||
const eventDetailStatus = createCustomEventDetail(
|
||||
FirefoxCommand.FxAStatus,
|
||||
{
|
||||
signedInUser: browserSignedInEmail,
|
||||
}
|
||||
);
|
||||
await page.goto(
|
||||
`${target.contentServerUrl}?automatedBrowser=true&${query.toString()}`
|
||||
);
|
||||
await login.respondToWebChannelMessage(eventDetailStatus);
|
||||
await login.checkWebChannelMessage('fxaccounts:fxa_status');
|
||||
expect(await login.getPrefilledEmail()).toContain(browserSignedInEmail);
|
||||
await login.setPassword(password);
|
||||
await login.clickSubmit();
|
||||
expect(await login.isUserLoggedIn()).toBe(true);
|
||||
});
|
||||
|
||||
test('Non-Sync settings page - no user signed into browser, user signed in locally', async ({
|
||||
target,
|
||||
}) => {
|
||||
const { login, page, settings } = syncBrowserPages;
|
||||
const query = new URLSearchParams({
|
||||
forceUA: uaStrings['desktop_firefox_71'],
|
||||
test('Non-Sync - user signed into browser, no user signed in locally', async ({
|
||||
target,
|
||||
}) => {
|
||||
const { login, page } = syncBrowserPages;
|
||||
const query = new URLSearchParams({
|
||||
forceUA: uaStrings['desktop_firefox_71'],
|
||||
email: browserSignedInEmail,
|
||||
});
|
||||
const eventDetailStatus = createCustomEventDetail(
|
||||
FirefoxCommand.FxAStatus,
|
||||
{
|
||||
signedInUser: browserSignedInEmail,
|
||||
}
|
||||
);
|
||||
await page.goto(
|
||||
`${target.contentServerUrl}?automatedBrowser=true&${query.toString()}`
|
||||
);
|
||||
await login.respondToWebChannelMessage(eventDetailStatus);
|
||||
await login.checkWebChannelMessage('fxaccounts:fxa_status');
|
||||
expect(await login.getPrefilledEmail()).toContain(browserSignedInEmail);
|
||||
await login.setPassword(password);
|
||||
await login.clickSubmit();
|
||||
expect(await login.isUserLoggedIn()).toBe(true);
|
||||
});
|
||||
await page.goto(
|
||||
`${target.contentServerUrl}?automatedBrowser=true&${query.toString()}`
|
||||
);
|
||||
await login.fillOutEmailFirstSignIn(otherEmail, password);
|
||||
expect(await login.isUserLoggedIn()).toBe(true);
|
||||
|
||||
await settings.goto();
|
||||
const primaryEmail = await settings.primaryEmail.statusText();
|
||||
expect(primaryEmail).toEqual(otherEmail);
|
||||
test('Non-Sync settings page - no user signed into browser, user signed in locally', async ({
|
||||
target,
|
||||
}) => {
|
||||
const { login, page, settings } = syncBrowserPages;
|
||||
const query = new URLSearchParams({
|
||||
forceUA: uaStrings['desktop_firefox_71'],
|
||||
});
|
||||
await page.goto(
|
||||
`${target.contentServerUrl}?automatedBrowser=true&${query.toString()}`
|
||||
);
|
||||
await login.fillOutEmailFirstSignIn(otherEmail, password);
|
||||
expect(await login.isUserLoggedIn()).toBe(true);
|
||||
|
||||
await settings.goto();
|
||||
const primaryEmail = await settings.primaryEmail.statusText();
|
||||
expect(primaryEmail).toEqual(otherEmail);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -13,181 +13,185 @@ let syncBrowserPages;
|
|||
|
||||
test.describe.configure({ mode: 'parallel' });
|
||||
|
||||
test.describe('Desktop Sync V3 force auth', () => {
|
||||
test.beforeEach(async ({ target }) => {
|
||||
test.slow();
|
||||
syncBrowserPages = await newPagesForSync(target);
|
||||
});
|
||||
|
||||
test.afterEach(async () => {
|
||||
await syncBrowserPages.browser?.close();
|
||||
});
|
||||
|
||||
test('sync v3 with a registered email, no uid', async ({
|
||||
credentials,
|
||||
target,
|
||||
}) => {
|
||||
const {
|
||||
fxDesktopV3ForceAuth,
|
||||
login,
|
||||
connectAnotherDevice,
|
||||
signinTokenCode,
|
||||
} = syncBrowserPages;
|
||||
|
||||
await fxDesktopV3ForceAuth.openWithReplacementParams(credentials, {
|
||||
uid: undefined,
|
||||
test.describe('severity-1 #smoke', () => {
|
||||
test.describe('Desktop Sync V3 force auth', () => {
|
||||
test.beforeEach(async ({ target }) => {
|
||||
test.slow();
|
||||
syncBrowserPages = await newPagesForSync(target);
|
||||
});
|
||||
await login.setPassword(credentials.password);
|
||||
await login.submit();
|
||||
expect(await signinTokenCode.tokenCodeHeader.isVisible()).toBeTruthy();
|
||||
await fxDesktopV3ForceAuth.checkWebChannelMessage(
|
||||
'fxaccounts:can_link_account'
|
||||
);
|
||||
await login.fillOutSignInCode(credentials.email);
|
||||
expect(await connectAnotherDevice.fxaConnected.isVisible()).toBeTruthy();
|
||||
await fxDesktopV3ForceAuth.checkWebChannelMessage('fxaccounts:login');
|
||||
});
|
||||
|
||||
test('sync v3 with a registered email, registered uid', async ({
|
||||
credentials,
|
||||
target,
|
||||
}) => {
|
||||
const {
|
||||
fxDesktopV3ForceAuth,
|
||||
login,
|
||||
connectAnotherDevice,
|
||||
signinTokenCode,
|
||||
} = syncBrowserPages;
|
||||
|
||||
await fxDesktopV3ForceAuth.open(credentials);
|
||||
await login.setPassword(credentials.password);
|
||||
await login.submit();
|
||||
expect(await signinTokenCode.tokenCodeHeader.isVisible()).toBeTruthy();
|
||||
await fxDesktopV3ForceAuth.checkWebChannelMessage(
|
||||
'fxaccounts:can_link_account'
|
||||
);
|
||||
await login.fillOutSignInCode(credentials.email);
|
||||
expect(await connectAnotherDevice.fxaConnected.isVisible()).toBeTruthy();
|
||||
await fxDesktopV3ForceAuth.checkWebChannelMessage('fxaccounts:login');
|
||||
});
|
||||
|
||||
test('sync v3 with a registered email, unregistered uid', async ({
|
||||
credentials,
|
||||
target,
|
||||
}) => {
|
||||
const {
|
||||
fxDesktopV3ForceAuth,
|
||||
login,
|
||||
connectAnotherDevice,
|
||||
signinTokenCode,
|
||||
} = syncBrowserPages;
|
||||
|
||||
const uid = makeUid();
|
||||
await fxDesktopV3ForceAuth.openWithReplacementParams(credentials, { uid });
|
||||
await fxDesktopV3ForceAuth.noSuchWebChannelMessage('fxaccounts:logout');
|
||||
await login.setPassword(credentials.password);
|
||||
await login.submit();
|
||||
expect(await signinTokenCode.tokenCodeHeader.isVisible()).toBeTruthy();
|
||||
await fxDesktopV3ForceAuth.checkWebChannelMessage(
|
||||
'fxaccounts:can_link_account'
|
||||
);
|
||||
await login.fillOutSignInCode(credentials.email);
|
||||
expect(await connectAnotherDevice.fxaConnected.isVisible()).toBeTruthy();
|
||||
await fxDesktopV3ForceAuth.checkWebChannelMessage('fxaccounts:login');
|
||||
});
|
||||
|
||||
test('sync v3 with an unregistered email, no uid', async ({
|
||||
credentials,
|
||||
target,
|
||||
}) => {
|
||||
const { fxDesktopV3ForceAuth, login } = syncBrowserPages;
|
||||
|
||||
const email = `sync${Math.random()}@restmail.net`;
|
||||
await fxDesktopV3ForceAuth.openWithReplacementParams(credentials, {
|
||||
email,
|
||||
uid: undefined,
|
||||
test.afterEach(async () => {
|
||||
await syncBrowserPages.browser?.close();
|
||||
});
|
||||
const error = await login.signInError();
|
||||
expect(error).toContain('Recreate');
|
||||
const emailInputValue = await login.getEmailInput();
|
||||
expect(emailInputValue).toBe(email);
|
||||
const emailInput = await login.getEmailInputElement();
|
||||
expect(emailInput.isDisabled());
|
||||
await expect(
|
||||
await (await login.getUseDifferentAccountLink()).count()
|
||||
).toEqual(0);
|
||||
await login.fillOutFirstSignUp(email, credentials.password, {
|
||||
enterEmail: false,
|
||||
|
||||
test('sync v3 with a registered email, no uid', async ({
|
||||
credentials,
|
||||
target,
|
||||
}) => {
|
||||
const {
|
||||
fxDesktopV3ForceAuth,
|
||||
login,
|
||||
connectAnotherDevice,
|
||||
signinTokenCode,
|
||||
} = syncBrowserPages;
|
||||
|
||||
await fxDesktopV3ForceAuth.openWithReplacementParams(credentials, {
|
||||
uid: undefined,
|
||||
});
|
||||
await login.setPassword(credentials.password);
|
||||
await login.submit();
|
||||
expect(await signinTokenCode.tokenCodeHeader.isVisible()).toBeTruthy();
|
||||
await fxDesktopV3ForceAuth.checkWebChannelMessage(
|
||||
'fxaccounts:can_link_account'
|
||||
);
|
||||
await login.fillOutSignInCode(credentials.email);
|
||||
expect(await connectAnotherDevice.fxaConnected.isVisible()).toBeTruthy();
|
||||
await fxDesktopV3ForceAuth.checkWebChannelMessage('fxaccounts:login');
|
||||
});
|
||||
await fxDesktopV3ForceAuth.checkWebChannelMessage(
|
||||
'fxaccounts:can_link_account'
|
||||
);
|
||||
await fxDesktopV3ForceAuth.checkWebChannelMessage('fxaccounts:login');
|
||||
});
|
||||
|
||||
test('sync v3 with an unregistered email, registered uid', async ({
|
||||
credentials,
|
||||
target,
|
||||
}) => {
|
||||
const { fxDesktopV3ForceAuth, login } = syncBrowserPages;
|
||||
test('sync v3 with a registered email, registered uid', async ({
|
||||
credentials,
|
||||
target,
|
||||
}) => {
|
||||
const {
|
||||
fxDesktopV3ForceAuth,
|
||||
login,
|
||||
connectAnotherDevice,
|
||||
signinTokenCode,
|
||||
} = syncBrowserPages;
|
||||
|
||||
const email = `sync${Math.random()}@restmail.net`;
|
||||
await fxDesktopV3ForceAuth.openWithReplacementParams(credentials, {
|
||||
email,
|
||||
await fxDesktopV3ForceAuth.open(credentials);
|
||||
await login.setPassword(credentials.password);
|
||||
await login.submit();
|
||||
expect(await signinTokenCode.tokenCodeHeader.isVisible()).toBeTruthy();
|
||||
await fxDesktopV3ForceAuth.checkWebChannelMessage(
|
||||
'fxaccounts:can_link_account'
|
||||
);
|
||||
await login.fillOutSignInCode(credentials.email);
|
||||
expect(await connectAnotherDevice.fxaConnected.isVisible()).toBeTruthy();
|
||||
await fxDesktopV3ForceAuth.checkWebChannelMessage('fxaccounts:login');
|
||||
});
|
||||
const error = await login.signInError();
|
||||
expect(error).toContain('Recreate');
|
||||
const emailInputValue = await login.getEmailInput();
|
||||
expect(emailInputValue).toBe(email);
|
||||
const emailInput = await login.getEmailInputElement();
|
||||
expect(emailInput.isDisabled());
|
||||
await expect(
|
||||
await (await login.getUseDifferentAccountLink()).count()
|
||||
).toEqual(0);
|
||||
});
|
||||
|
||||
test('sync v3 with an unregistered email, unregistered uid', async ({
|
||||
credentials,
|
||||
target,
|
||||
}) => {
|
||||
const { fxDesktopV3ForceAuth, login } = syncBrowserPages;
|
||||
test('sync v3 with a registered email, unregistered uid', async ({
|
||||
credentials,
|
||||
target,
|
||||
}) => {
|
||||
const {
|
||||
fxDesktopV3ForceAuth,
|
||||
login,
|
||||
connectAnotherDevice,
|
||||
signinTokenCode,
|
||||
} = syncBrowserPages;
|
||||
|
||||
const email = `sync${Math.random()}@restmail.net`;
|
||||
const uid = makeUid();
|
||||
await fxDesktopV3ForceAuth.openWithReplacementParams(credentials, {
|
||||
email,
|
||||
uid,
|
||||
const uid = makeUid();
|
||||
await fxDesktopV3ForceAuth.openWithReplacementParams(credentials, {
|
||||
uid,
|
||||
});
|
||||
await fxDesktopV3ForceAuth.noSuchWebChannelMessage('fxaccounts:logout');
|
||||
await login.setPassword(credentials.password);
|
||||
await login.submit();
|
||||
expect(await signinTokenCode.tokenCodeHeader.isVisible()).toBeTruthy();
|
||||
await fxDesktopV3ForceAuth.checkWebChannelMessage(
|
||||
'fxaccounts:can_link_account'
|
||||
);
|
||||
await login.fillOutSignInCode(credentials.email);
|
||||
expect(await connectAnotherDevice.fxaConnected.isVisible()).toBeTruthy();
|
||||
await fxDesktopV3ForceAuth.checkWebChannelMessage('fxaccounts:login');
|
||||
});
|
||||
const error = await login.signInError();
|
||||
expect(error).toContain('Recreate');
|
||||
const emailInputValue = await login.getEmailInput();
|
||||
expect(emailInputValue).toBe(email);
|
||||
const emailInput = await login.getEmailInputElement();
|
||||
expect(emailInput.isDisabled());
|
||||
await expect(
|
||||
await (await login.getUseDifferentAccountLink()).count()
|
||||
).toEqual(0);
|
||||
});
|
||||
|
||||
test('blocked with an registered email, unregistered uid', async ({
|
||||
credentials,
|
||||
target,
|
||||
}) => {
|
||||
const { fxDesktopV3ForceAuth, login, connectAnotherDevice } =
|
||||
syncBrowserPages;
|
||||
test('sync v3 with an unregistered email, no uid', async ({
|
||||
credentials,
|
||||
target,
|
||||
}) => {
|
||||
const { fxDesktopV3ForceAuth, login } = syncBrowserPages;
|
||||
|
||||
const uid = makeUid();
|
||||
await fxDesktopV3ForceAuth.openWithReplacementParams(credentials, {
|
||||
uid,
|
||||
const email = `sync${Math.random()}@restmail.net`;
|
||||
await fxDesktopV3ForceAuth.openWithReplacementParams(credentials, {
|
||||
email,
|
||||
uid: undefined,
|
||||
});
|
||||
const error = await login.signInError();
|
||||
expect(error).toContain('Recreate');
|
||||
const emailInputValue = await login.getEmailInput();
|
||||
expect(emailInputValue).toBe(email);
|
||||
const emailInput = await login.getEmailInputElement();
|
||||
expect(emailInput.isDisabled());
|
||||
await expect(
|
||||
await (await login.getUseDifferentAccountLink()).count()
|
||||
).toEqual(0);
|
||||
await login.fillOutFirstSignUp(email, credentials.password, {
|
||||
enterEmail: false,
|
||||
});
|
||||
await fxDesktopV3ForceAuth.checkWebChannelMessage(
|
||||
'fxaccounts:can_link_account'
|
||||
);
|
||||
await fxDesktopV3ForceAuth.checkWebChannelMessage('fxaccounts:login');
|
||||
});
|
||||
|
||||
test('sync v3 with an unregistered email, registered uid', async ({
|
||||
credentials,
|
||||
target,
|
||||
}) => {
|
||||
const { fxDesktopV3ForceAuth, login } = syncBrowserPages;
|
||||
|
||||
const email = `sync${Math.random()}@restmail.net`;
|
||||
await fxDesktopV3ForceAuth.openWithReplacementParams(credentials, {
|
||||
email,
|
||||
});
|
||||
const error = await login.signInError();
|
||||
expect(error).toContain('Recreate');
|
||||
const emailInputValue = await login.getEmailInput();
|
||||
expect(emailInputValue).toBe(email);
|
||||
const emailInput = await login.getEmailInputElement();
|
||||
expect(emailInput.isDisabled());
|
||||
await expect(
|
||||
await (await login.getUseDifferentAccountLink()).count()
|
||||
).toEqual(0);
|
||||
});
|
||||
|
||||
test('sync v3 with an unregistered email, unregistered uid', async ({
|
||||
credentials,
|
||||
target,
|
||||
}) => {
|
||||
const { fxDesktopV3ForceAuth, login } = syncBrowserPages;
|
||||
|
||||
const email = `sync${Math.random()}@restmail.net`;
|
||||
const uid = makeUid();
|
||||
await fxDesktopV3ForceAuth.openWithReplacementParams(credentials, {
|
||||
email,
|
||||
uid,
|
||||
});
|
||||
const error = await login.signInError();
|
||||
expect(error).toContain('Recreate');
|
||||
const emailInputValue = await login.getEmailInput();
|
||||
expect(emailInputValue).toBe(email);
|
||||
const emailInput = await login.getEmailInputElement();
|
||||
expect(emailInput.isDisabled());
|
||||
await expect(
|
||||
await (await login.getUseDifferentAccountLink()).count()
|
||||
).toEqual(0);
|
||||
});
|
||||
|
||||
test('blocked with an registered email, unregistered uid', async ({
|
||||
credentials,
|
||||
target,
|
||||
}) => {
|
||||
const { fxDesktopV3ForceAuth, login, connectAnotherDevice } =
|
||||
syncBrowserPages;
|
||||
|
||||
const uid = makeUid();
|
||||
await fxDesktopV3ForceAuth.openWithReplacementParams(credentials, {
|
||||
uid,
|
||||
});
|
||||
await fxDesktopV3ForceAuth.noSuchWebChannelMessage('fxaccounts:logout');
|
||||
await login.setPassword(credentials.password);
|
||||
await login.submit();
|
||||
await fxDesktopV3ForceAuth.checkWebChannelMessage(
|
||||
'fxaccounts:can_link_account'
|
||||
);
|
||||
await login.unblock(credentials.email);
|
||||
expect(await connectAnotherDevice.fxaConnected.isVisible()).toBeTruthy();
|
||||
await fxDesktopV3ForceAuth.checkWebChannelMessage('fxaccounts:login');
|
||||
});
|
||||
await fxDesktopV3ForceAuth.noSuchWebChannelMessage('fxaccounts:logout');
|
||||
await login.setPassword(credentials.password);
|
||||
await login.submit();
|
||||
await fxDesktopV3ForceAuth.checkWebChannelMessage(
|
||||
'fxaccounts:can_link_account'
|
||||
);
|
||||
await login.unblock(credentials.email);
|
||||
expect(await connectAnotherDevice.fxaConnected.isVisible()).toBeTruthy();
|
||||
await fxDesktopV3ForceAuth.checkWebChannelMessage('fxaccounts:login');
|
||||
});
|
||||
});
|
||||
|
|
|
@ -12,120 +12,122 @@ let syncBrowserPages;
|
|||
|
||||
test.describe.configure({ mode: 'parallel' });
|
||||
|
||||
test.describe('Firefox Desktop Sync v3 settings', () => {
|
||||
test.beforeEach(async ({ target }) => {
|
||||
test.slow();
|
||||
syncBrowserPages = await newPagesForSync(target);
|
||||
const { login, connectAnotherDevice, page } = syncBrowserPages;
|
||||
email = login.createEmail('sync{id}');
|
||||
await target.auth.signUp(email, firstPassword, {
|
||||
lang: 'en',
|
||||
preVerified: 'true',
|
||||
test.describe('severity-2 #smoke', () => {
|
||||
test.describe('Firefox Desktop Sync v3 settings', () => {
|
||||
test.beforeEach(async ({ target }) => {
|
||||
test.slow();
|
||||
syncBrowserPages = await newPagesForSync(target);
|
||||
const { login, connectAnotherDevice, page } = syncBrowserPages;
|
||||
email = login.createEmail('sync{id}');
|
||||
await target.auth.signUp(email, firstPassword, {
|
||||
lang: 'en',
|
||||
preVerified: 'true',
|
||||
});
|
||||
const customEventDetail = createCustomEventDetail(
|
||||
FirefoxCommand.LinkAccount,
|
||||
{
|
||||
ok: true,
|
||||
}
|
||||
);
|
||||
await page.goto(
|
||||
`${target.contentServerUrl}?context=fx_desktop_v3&service=sync&action=email`
|
||||
);
|
||||
await login.respondToWebChannelMessage(customEventDetail);
|
||||
await login.fillOutEmailFirstSignIn(email, firstPassword);
|
||||
await login.waitForSignInCodeHeader();
|
||||
|
||||
await login.checkWebChannelMessage(FirefoxCommand.LinkAccount);
|
||||
await login.fillOutSignInCode(email);
|
||||
await login.checkWebChannelMessage(FirefoxCommand.Login);
|
||||
expect(await connectAnotherDevice.fxaConnected.isEnabled()).toBeTruthy();
|
||||
});
|
||||
const customEventDetail = createCustomEventDetail(
|
||||
FirefoxCommand.LinkAccount,
|
||||
{
|
||||
ok: true,
|
||||
|
||||
test.afterEach(async ({ target }, test) => {
|
||||
await syncBrowserPages.browser?.close();
|
||||
if (email) {
|
||||
// Cleanup any accounts created during the test
|
||||
try {
|
||||
await target.auth.accountDestroy(email, secondPassword);
|
||||
} catch (e) {
|
||||
// Handle the error here
|
||||
console.error('An error occurred during account cleanup:', e);
|
||||
// Optionally, rethrow the error to propagate it further
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
);
|
||||
await page.goto(
|
||||
`${target.contentServerUrl}?context=fx_desktop_v3&service=sync&action=email`
|
||||
);
|
||||
await login.respondToWebChannelMessage(customEventDetail);
|
||||
await login.fillOutEmailFirstSignIn(email, firstPassword);
|
||||
await login.waitForSignInCodeHeader();
|
||||
});
|
||||
|
||||
await login.checkWebChannelMessage(FirefoxCommand.LinkAccount);
|
||||
await login.fillOutSignInCode(email);
|
||||
await login.checkWebChannelMessage(FirefoxCommand.Login);
|
||||
expect(await connectAnotherDevice.fxaConnected.isEnabled()).toBeTruthy();
|
||||
test('sign in, change the password', async ({ target }) => {
|
||||
const { changePassword, settings, page } = syncBrowserPages;
|
||||
|
||||
//Goto settings sync url
|
||||
await page.goto(
|
||||
`${target.contentServerUrl}/settings?context=fx_desktop_v3&service=sync`
|
||||
);
|
||||
|
||||
//Change password
|
||||
await settings.password.clickChange();
|
||||
await changePassword.fillOutChangePassword(firstPassword, secondPassword);
|
||||
await changePassword.submit();
|
||||
|
||||
//Verify success message
|
||||
expect(await changePassword.changePasswordSuccess()).toContain(
|
||||
'Password updated'
|
||||
);
|
||||
});
|
||||
|
||||
test('sign in, change the password by browsing directly to settings', async ({
|
||||
target,
|
||||
}) => {
|
||||
const { login, changePassword, settings } = syncBrowserPages;
|
||||
|
||||
//Goto settings non-sync url
|
||||
await settings.goto();
|
||||
|
||||
//Change password
|
||||
await settings.password.clickChange();
|
||||
await login.noSuchWebChannelMessage(FirefoxCommand.ChangePassword);
|
||||
await changePassword.fillOutChangePassword(firstPassword, secondPassword);
|
||||
await changePassword.submit();
|
||||
|
||||
//Verify success message
|
||||
expect(await changePassword.changePasswordSuccess()).toContain(
|
||||
'Password updated'
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
test.afterEach(async ({ target }, test) => {
|
||||
await syncBrowserPages.browser?.close();
|
||||
if (email) {
|
||||
// Cleanup any accounts created during the test
|
||||
try {
|
||||
await target.auth.accountDestroy(email, secondPassword);
|
||||
} catch (e) {
|
||||
// Handle the error here
|
||||
console.error('An error occurred during account cleanup:', e);
|
||||
// Optionally, rethrow the error to propagate it further
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
});
|
||||
test.describe('Firefox Desktop Sync v3 settings - delete account', () => {
|
||||
test('sign in, delete the account', async ({ target }) => {
|
||||
syncBrowserPages = await newPagesForSync(target);
|
||||
const { login, settings, deleteAccount, page } = syncBrowserPages;
|
||||
test.slow();
|
||||
email = login.createEmail('sync{id}');
|
||||
await target.auth.signUp(email, firstPassword, {
|
||||
lang: 'en',
|
||||
preVerified: 'true',
|
||||
});
|
||||
await page.goto(
|
||||
`${target.contentServerUrl}?context=fx_desktop_v3&service=sync&action=email`
|
||||
);
|
||||
await login.fillOutEmailFirstSignIn(email, firstPassword);
|
||||
await login.fillOutSignInCode(email);
|
||||
|
||||
test('sign in, change the password', async ({ target }) => {
|
||||
const { changePassword, settings, page } = syncBrowserPages;
|
||||
//Go to setting page
|
||||
await page.goto(
|
||||
`${target.contentServerUrl}/settings?context=fx_desktop_v3&service=sync`
|
||||
);
|
||||
//Click Delete account
|
||||
await settings.clickDeleteAccount();
|
||||
await deleteAccount.checkAllBoxes();
|
||||
await deleteAccount.clickContinue();
|
||||
|
||||
//Goto settings sync url
|
||||
await page.goto(
|
||||
`${target.contentServerUrl}/settings?context=fx_desktop_v3&service=sync`
|
||||
);
|
||||
//Enter password
|
||||
await deleteAccount.setPassword(firstPassword);
|
||||
await deleteAccount.submit();
|
||||
|
||||
//Change password
|
||||
await settings.password.clickChange();
|
||||
await changePassword.fillOutChangePassword(firstPassword, secondPassword);
|
||||
await changePassword.submit();
|
||||
|
||||
//Verify success message
|
||||
expect(await changePassword.changePasswordSuccess()).toContain(
|
||||
'Password updated'
|
||||
);
|
||||
});
|
||||
|
||||
test('sign in, change the password by browsing directly to settings', async ({
|
||||
target,
|
||||
}) => {
|
||||
const { login, changePassword, settings } = syncBrowserPages;
|
||||
|
||||
//Goto settings non-sync url
|
||||
await settings.goto();
|
||||
|
||||
//Change password
|
||||
await settings.password.clickChange();
|
||||
await login.noSuchWebChannelMessage(FirefoxCommand.ChangePassword);
|
||||
await changePassword.fillOutChangePassword(firstPassword, secondPassword);
|
||||
await changePassword.submit();
|
||||
|
||||
//Verify success message
|
||||
expect(await changePassword.changePasswordSuccess()).toContain(
|
||||
'Password updated'
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
test.describe('Firefox Desktop Sync v3 settings - delete account', () => {
|
||||
test('sign in, delete the account', async ({ target }) => {
|
||||
syncBrowserPages = await newPagesForSync(target);
|
||||
const { login, settings, deleteAccount, page } = syncBrowserPages;
|
||||
test.slow();
|
||||
email = login.createEmail('sync{id}');
|
||||
await target.auth.signUp(email, firstPassword, {
|
||||
lang: 'en',
|
||||
preVerified: 'true',
|
||||
});
|
||||
await page.goto(
|
||||
`${target.contentServerUrl}?context=fx_desktop_v3&service=sync&action=email`
|
||||
);
|
||||
await login.fillOutEmailFirstSignIn(email, firstPassword);
|
||||
await login.fillOutSignInCode(email);
|
||||
|
||||
//Go to setting page
|
||||
await page.goto(
|
||||
`${target.contentServerUrl}/settings?context=fx_desktop_v3&service=sync`
|
||||
);
|
||||
//Click Delete account
|
||||
await settings.clickDeleteAccount();
|
||||
await deleteAccount.checkAllBoxes();
|
||||
await deleteAccount.clickContinue();
|
||||
|
||||
//Enter password
|
||||
await deleteAccount.setPassword(firstPassword);
|
||||
await deleteAccount.submit();
|
||||
|
||||
const success = await page.waitForSelector('.success');
|
||||
expect(await success.isVisible()).toBeTruthy();
|
||||
const success = await page.waitForSelector('.success');
|
||||
expect(await success.isVisible()).toBeTruthy();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -11,195 +11,208 @@ let syncBrowserPages;
|
|||
|
||||
test.describe.configure({ mode: 'parallel' });
|
||||
|
||||
test.describe('Firefox Desktop Sync v3 sign in', () => {
|
||||
test.beforeEach(async ({ target }) => {
|
||||
test.slow();
|
||||
syncBrowserPages = await newPagesForSync(target);
|
||||
const { login } = syncBrowserPages;
|
||||
email = login.createEmail('sync{id}');
|
||||
});
|
||||
|
||||
test.afterEach(async () => {
|
||||
test.slow();//The cleanup was timing out and exceeding 3000ms
|
||||
await syncBrowserPages.browser?.close();
|
||||
});
|
||||
|
||||
test('verified, does not need to confirm', async ({ target }) => {
|
||||
const { page, login, connectAnotherDevice, signinTokenCode } =
|
||||
syncBrowserPages;
|
||||
const email = login.createEmail();
|
||||
await target.auth.signUp(email, password, {
|
||||
lang: 'en',
|
||||
preVerified: 'true',
|
||||
test.describe('severity-2 #smoke', () => {
|
||||
test.describe('Firefox Desktop Sync v3 sign in', () => {
|
||||
test.beforeEach(async ({ target }) => {
|
||||
test.slow();
|
||||
syncBrowserPages = await newPagesForSync(target);
|
||||
const { login } = syncBrowserPages;
|
||||
email = login.createEmail('sync{id}');
|
||||
});
|
||||
await page.goto(
|
||||
`${target.contentServerUrl}?context=fx_desktop_v3&service=sync&action=email`
|
||||
);
|
||||
await login.setEmail(email);
|
||||
await signinTokenCode.clickSubmitButton();
|
||||
await login.setPassword(password);
|
||||
await login.submit();
|
||||
expect(await connectAnotherDevice.fxaConnected.isEnabled()).toBeTruthy();
|
||||
});
|
||||
|
||||
test('verified, resend', async ({ target }) => {
|
||||
const { page, login, connectAnotherDevice, signinTokenCode } =
|
||||
syncBrowserPages;
|
||||
|
||||
await page.goto(
|
||||
`${target.contentServerUrl}?context=fx_desktop_v3&service=sync&action=email`
|
||||
);
|
||||
await login.setEmail(email);
|
||||
await signinTokenCode.clickSubmitButton();
|
||||
await login.setPassword(password);
|
||||
await login.confirmPassword(password);
|
||||
await login.setAge('21');
|
||||
await login.submit();
|
||||
|
||||
// Click resend link
|
||||
await signinTokenCode.resendLink.click();
|
||||
await signinTokenCode.successMessage.waitFor({ state: 'visible' });
|
||||
await expect(signinTokenCode.successMessage).toBeVisible();
|
||||
await expect(signinTokenCode.successMessage).toContainText('Email resent.');
|
||||
const code = await target.email.waitForEmail(
|
||||
email,
|
||||
EmailType.verifyShortCode,
|
||||
EmailHeader.shortCode
|
||||
);
|
||||
await signinTokenCode.input.fill(code);
|
||||
await login.submit();
|
||||
expect(await connectAnotherDevice.fxaConnected.isVisible()).toBeTruthy();
|
||||
});
|
||||
|
||||
test('verified - invalid code', async ({ target }) => {
|
||||
const { page, login, connectAnotherDevice, signinTokenCode } =
|
||||
syncBrowserPages;
|
||||
|
||||
await page.goto(
|
||||
`${target.contentServerUrl}?context=fx_desktop_v3&service=sync&action=email`
|
||||
);
|
||||
await login.setEmail(email);
|
||||
await signinTokenCode.clickSubmitButton();
|
||||
await login.setPassword(password);
|
||||
await login.confirmPassword(password);
|
||||
await login.setAge('21');
|
||||
await login.submit();
|
||||
|
||||
// Input invalid code and verify the tooltip error
|
||||
await signinTokenCode.input.fill('000000');
|
||||
await signinTokenCode.submit.click();
|
||||
await expect(signinTokenCode.tooltip).toContainText('Invalid or expired');
|
||||
|
||||
//Input Valid code and verify the success
|
||||
await login.fillOutSignUpCode(email);
|
||||
expect(await connectAnotherDevice.fxaConnected.isVisible()).toBeTruthy();
|
||||
});
|
||||
|
||||
test('verified, blocked', async ({ target }) => {
|
||||
const { page, login, connectAnotherDevice, signinTokenCode } =
|
||||
syncBrowserPages;
|
||||
|
||||
const blockedEmail = login.createEmail('blocked{id}');
|
||||
await target.auth.signUp(blockedEmail, password, {
|
||||
lang: 'en',
|
||||
preVerified: 'true',
|
||||
test.afterEach(async () => {
|
||||
test.slow(); //The cleanup was timing out and exceeding 3000ms
|
||||
await syncBrowserPages.browser?.close();
|
||||
});
|
||||
await page.goto(
|
||||
`${target.contentServerUrl}?context=fx_desktop_v3&service=sync`
|
||||
);
|
||||
await login.setEmail(blockedEmail);
|
||||
await signinTokenCode.clickSubmitButton();
|
||||
await login.setPassword(password);
|
||||
await login.submit();
|
||||
await login.unblock(blockedEmail);
|
||||
expect(await connectAnotherDevice.fxaConnected.isVisible()).toBeTruthy();
|
||||
});
|
||||
|
||||
test('unverified', async ({ target }) => {
|
||||
const { page, login, connectAnotherDevice, signinTokenCode } =
|
||||
syncBrowserPages;
|
||||
|
||||
await target.auth.signUp(email, password, {
|
||||
lang: 'en',
|
||||
preVerified: 'false',
|
||||
test('verified, does not need to confirm', async ({ target }) => {
|
||||
const { page, login, connectAnotherDevice, signinTokenCode } =
|
||||
syncBrowserPages;
|
||||
const email = login.createEmail();
|
||||
await target.auth.signUp(email, password, {
|
||||
lang: 'en',
|
||||
preVerified: 'true',
|
||||
});
|
||||
await page.goto(
|
||||
`${target.contentServerUrl}?context=fx_desktop_v3&service=sync&action=email`
|
||||
);
|
||||
await login.setEmail(email);
|
||||
await signinTokenCode.clickSubmitButton();
|
||||
await login.setPassword(password);
|
||||
await login.submit();
|
||||
expect(await connectAnotherDevice.fxaConnected.isEnabled()).toBeTruthy();
|
||||
});
|
||||
await page.goto(
|
||||
`${target.contentServerUrl}?context=fx_desktop_v3&service=sync&action=email`
|
||||
);
|
||||
await login.setEmail(email);
|
||||
await signinTokenCode.clickSubmitButton();
|
||||
await login.setPassword(password);
|
||||
await login.submit();
|
||||
await login.fillOutSignInCode(email);
|
||||
expect(await connectAnotherDevice.fxaConnected.isVisible()).toBeTruthy();
|
||||
});
|
||||
|
||||
test('add TOTP and confirm sync signin', async ({ credentials, target }) => {
|
||||
const { page, login, connectAnotherDevice, settings, totp } =
|
||||
syncBrowserPages;
|
||||
test('verified, resend', async ({ target }) => {
|
||||
const { page, login, connectAnotherDevice, signinTokenCode } =
|
||||
syncBrowserPages;
|
||||
|
||||
await settings.goto();
|
||||
await settings.totp.clickAdd();
|
||||
await totp.enable(credentials);
|
||||
await settings.signOut();
|
||||
await page.goto(
|
||||
`${target.contentServerUrl}?context=fx_desktop_v3&service=sync&action=email`
|
||||
);
|
||||
await login.setEmail(email);
|
||||
await signinTokenCode.clickSubmitButton();
|
||||
await login.setPassword(password);
|
||||
await login.confirmPassword(password);
|
||||
await login.setAge('21');
|
||||
await login.submit();
|
||||
|
||||
// Sync sign in
|
||||
await page.goto(
|
||||
`${target.contentServerUrl}?context=fx_desktop_v3&service=sync`,
|
||||
{ waitUntil: 'load' }
|
||||
);
|
||||
await login.login(credentials.email, credentials.password);
|
||||
await login.setTotp(credentials.secret);
|
||||
expect(await connectAnotherDevice.fxaConnected.isVisible()).toBeTruthy();
|
||||
// Click resend link
|
||||
await signinTokenCode.resendLink.click();
|
||||
await signinTokenCode.successMessage.waitFor({ state: 'visible' });
|
||||
await expect(signinTokenCode.successMessage).toBeVisible();
|
||||
await expect(signinTokenCode.successMessage).toContainText(
|
||||
'Email resent.'
|
||||
);
|
||||
const code = await target.email.waitForEmail(
|
||||
email,
|
||||
EmailType.verifyShortCode,
|
||||
EmailHeader.shortCode
|
||||
);
|
||||
await signinTokenCode.input.fill(code);
|
||||
await login.submit();
|
||||
expect(await connectAnotherDevice.fxaConnected.isVisible()).toBeTruthy();
|
||||
});
|
||||
|
||||
test('verified - invalid code', async ({ target }) => {
|
||||
const { page, login, connectAnotherDevice, signinTokenCode } =
|
||||
syncBrowserPages;
|
||||
|
||||
await page.goto(
|
||||
`${target.contentServerUrl}?context=fx_desktop_v3&service=sync&action=email`
|
||||
);
|
||||
await login.setEmail(email);
|
||||
await signinTokenCode.clickSubmitButton();
|
||||
await login.setPassword(password);
|
||||
await login.confirmPassword(password);
|
||||
await login.setAge('21');
|
||||
await login.submit();
|
||||
|
||||
// Input invalid code and verify the tooltip error
|
||||
await signinTokenCode.input.fill('000000');
|
||||
await signinTokenCode.submit.click();
|
||||
await expect(signinTokenCode.tooltip).toContainText('Invalid or expired');
|
||||
|
||||
//Input Valid code and verify the success
|
||||
await login.fillOutSignUpCode(email);
|
||||
expect(await connectAnotherDevice.fxaConnected.isVisible()).toBeTruthy();
|
||||
});
|
||||
|
||||
test('verified, blocked', async ({ target }) => {
|
||||
const { page, login, connectAnotherDevice, signinTokenCode } =
|
||||
syncBrowserPages;
|
||||
|
||||
const blockedEmail = login.createEmail('blocked{id}');
|
||||
await target.auth.signUp(blockedEmail, password, {
|
||||
lang: 'en',
|
||||
preVerified: 'true',
|
||||
});
|
||||
await page.goto(
|
||||
`${target.contentServerUrl}?context=fx_desktop_v3&service=sync`
|
||||
);
|
||||
await login.setEmail(blockedEmail);
|
||||
await signinTokenCode.clickSubmitButton();
|
||||
await login.setPassword(password);
|
||||
await login.submit();
|
||||
await login.unblock(blockedEmail);
|
||||
expect(await connectAnotherDevice.fxaConnected.isVisible()).toBeTruthy();
|
||||
});
|
||||
|
||||
test('unverified', async ({ target }) => {
|
||||
const { page, login, connectAnotherDevice, signinTokenCode } =
|
||||
syncBrowserPages;
|
||||
|
||||
await target.auth.signUp(email, password, {
|
||||
lang: 'en',
|
||||
preVerified: 'false',
|
||||
});
|
||||
await page.goto(
|
||||
`${target.contentServerUrl}?context=fx_desktop_v3&service=sync&action=email`
|
||||
);
|
||||
await login.setEmail(email);
|
||||
await signinTokenCode.clickSubmitButton();
|
||||
await login.setPassword(password);
|
||||
await login.submit();
|
||||
await login.fillOutSignInCode(email);
|
||||
expect(await connectAnotherDevice.fxaConnected.isVisible()).toBeTruthy();
|
||||
});
|
||||
|
||||
test('add TOTP and confirm sync signin', async ({
|
||||
credentials,
|
||||
target,
|
||||
}) => {
|
||||
const { page, login, connectAnotherDevice, settings, totp } =
|
||||
syncBrowserPages;
|
||||
|
||||
await settings.goto();
|
||||
await settings.totp.clickAdd();
|
||||
await totp.enable(credentials);
|
||||
await settings.signOut();
|
||||
|
||||
// Sync sign in
|
||||
await page.goto(
|
||||
`${target.contentServerUrl}?context=fx_desktop_v3&service=sync`,
|
||||
{ waitUntil: 'load' }
|
||||
);
|
||||
await login.login(credentials.email, credentials.password);
|
||||
await login.setTotp(credentials.secret);
|
||||
expect(await connectAnotherDevice.fxaConnected.isVisible()).toBeTruthy();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
test.describe('OAuth and Fx Desktop handshake', () => {
|
||||
test('user signed into browser and OAuth login', async ({
|
||||
target,
|
||||
credentials,
|
||||
}) => {
|
||||
const { browser, page, login, relier, settings } = await newPagesForSync(
|
||||
target
|
||||
);
|
||||
await page.goto(
|
||||
target.contentServerUrl +
|
||||
'?context=fx_desktop_v3&entrypoint=fxa%3Aenter_email&service=sync&action=email'
|
||||
);
|
||||
await login.login(credentials.email, credentials.password);
|
||||
expect(await login.isSyncConnectedHeader()).toBe(true);
|
||||
test.describe('severity-1 #smoke', () => {
|
||||
test.describe('OAuth and Fx Desktop handshake', () => {
|
||||
test('user signed into browser and OAuth login', async ({
|
||||
target,
|
||||
credentials,
|
||||
}) => {
|
||||
const { browser, page, login, relier, settings } = await newPagesForSync(
|
||||
target
|
||||
);
|
||||
await page.goto(
|
||||
target.contentServerUrl +
|
||||
'?context=fx_desktop_v3&entrypoint=fxa%3Aenter_email&service=sync&action=email'
|
||||
);
|
||||
await login.login(credentials.email, credentials.password);
|
||||
expect(await login.isSyncConnectedHeader()).toBe(true);
|
||||
|
||||
// Normally we wouldn't need this delay, but because we are
|
||||
// disconnecting the sync service, we need to ensure that the device
|
||||
// record and web channels have been sent and created.
|
||||
await page.waitForTimeout(1000);
|
||||
// Normally we wouldn't need this delay, but because we are
|
||||
// disconnecting the sync service, we need to ensure that the device
|
||||
// record and web channels have been sent and created.
|
||||
await page.waitForTimeout(1000);
|
||||
|
||||
await relier.goto();
|
||||
await relier.clickEmailFirst();
|
||||
await relier.goto();
|
||||
await relier.clickEmailFirst();
|
||||
|
||||
// User can sign in with cached credentials, no password needed.
|
||||
await expect(await login.getPrefilledEmail()).toContain(credentials.email);
|
||||
await expect(await login.isCachedLogin()).toBe(true);
|
||||
// User can sign in with cached credentials, no password needed.
|
||||
await expect(await login.getPrefilledEmail()).toContain(
|
||||
credentials.email
|
||||
);
|
||||
await expect(await login.isCachedLogin()).toBe(true);
|
||||
|
||||
await login.submit();
|
||||
expect(await relier.isLoggedIn()).toBe(true);
|
||||
await login.submit();
|
||||
expect(await relier.isLoggedIn()).toBe(true);
|
||||
|
||||
await relier.signOut();
|
||||
await relier.signOut();
|
||||
|
||||
// Attempt to sign back in
|
||||
await relier.clickEmailFirst();
|
||||
// Attempt to sign back in
|
||||
await relier.clickEmailFirst();
|
||||
|
||||
await expect(await login.getPrefilledEmail()).toContain(credentials.email);
|
||||
await expect(await login.isCachedLogin()).toBe(true);
|
||||
await expect(await login.getPrefilledEmail()).toContain(
|
||||
credentials.email
|
||||
);
|
||||
await expect(await login.isCachedLogin()).toBe(true);
|
||||
|
||||
await login.submit();
|
||||
expect(await relier.isLoggedIn()).toBe(true);
|
||||
await login.submit();
|
||||
expect(await relier.isLoggedIn()).toBe(true);
|
||||
|
||||
// Disconnect sync otherwise we can have flaky tests.
|
||||
await settings.disconnectSync(credentials);
|
||||
// Disconnect sync otherwise we can have flaky tests.
|
||||
await settings.disconnectSync(credentials);
|
||||
|
||||
expect(page.url()).toContain(login.url);
|
||||
expect(page.url()).toContain(login.url);
|
||||
|
||||
await browser?.close();
|
||||
await browser?.close();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -10,128 +10,130 @@ let email, syncBrowserPages;
|
|||
|
||||
test.describe.configure({ mode: 'parallel' });
|
||||
|
||||
test.describe('Firefox Desktop Sync v3 sign up', () => {
|
||||
test.beforeEach(async ({ target, pages: { login } }) => {
|
||||
test.slow();
|
||||
email = login.createEmail('sync{id}');
|
||||
syncBrowserPages = await newPagesForSync(target);
|
||||
});
|
||||
test.describe('severity-1 #smoke', () => {
|
||||
test.describe('Firefox Desktop Sync v3 sign up', () => {
|
||||
test.beforeEach(async ({ target, pages: { login } }) => {
|
||||
test.slow();
|
||||
email = login.createEmail('sync{id}');
|
||||
syncBrowserPages = await newPagesForSync(target);
|
||||
});
|
||||
|
||||
test.afterEach(async () => {
|
||||
await syncBrowserPages.browser?.close();
|
||||
});
|
||||
test.afterEach(async () => {
|
||||
await syncBrowserPages.browser?.close();
|
||||
});
|
||||
|
||||
test('sync sign up', async ({ target }) => {
|
||||
const { page, login, connectAnotherDevice, signinTokenCode } =
|
||||
syncBrowserPages;
|
||||
test('sync sign up', async ({ target }) => {
|
||||
const { page, login, connectAnotherDevice, signinTokenCode } =
|
||||
syncBrowserPages;
|
||||
|
||||
await page.goto(
|
||||
`${target.contentServerUrl}?context=fx_desktop_v3&service=sync&action=email`,
|
||||
{ waitUntil: 'load' }
|
||||
);
|
||||
await login.setEmail(email);
|
||||
await signinTokenCode.clickSubmitButton();
|
||||
await page.goto(
|
||||
`${target.contentServerUrl}?context=fx_desktop_v3&service=sync&action=email`,
|
||||
{ waitUntil: 'load' }
|
||||
);
|
||||
await login.setEmail(email);
|
||||
await signinTokenCode.clickSubmitButton();
|
||||
|
||||
// Verify the email is correct
|
||||
expect(await login.getPrefilledEmail()).toMatch(email);
|
||||
// Verify the email is correct
|
||||
expect(await login.getPrefilledEmail()).toMatch(email);
|
||||
|
||||
// Passwords do not match should cause an error
|
||||
await login.setPassword(password);
|
||||
await login.confirmPassword(incorrectPassword);
|
||||
await login.setAge('21');
|
||||
await signinTokenCode.clickSubmitButton();
|
||||
// Passwords do not match should cause an error
|
||||
await login.setPassword(password);
|
||||
await login.confirmPassword(incorrectPassword);
|
||||
await login.setAge('21');
|
||||
await signinTokenCode.clickSubmitButton();
|
||||
|
||||
// Verify the error message
|
||||
expect(await login.getTooltipError()).toContain('Passwords do not match');
|
||||
// Verify the error message
|
||||
expect(await login.getTooltipError()).toContain('Passwords do not match');
|
||||
|
||||
// Fix the error
|
||||
await login.confirmPassword(password);
|
||||
await login.submit();
|
||||
await login.fillOutSignUpCode(email);
|
||||
expect(await connectAnotherDevice.fxaConnected.isVisible()).toBeTruthy();
|
||||
});
|
||||
// Fix the error
|
||||
await login.confirmPassword(password);
|
||||
await login.submit();
|
||||
await login.fillOutSignUpCode(email);
|
||||
expect(await connectAnotherDevice.fxaConnected.isVisible()).toBeTruthy();
|
||||
});
|
||||
|
||||
test('coppa disabled', async ({ target }) => {
|
||||
const { page, login, connectAnotherDevice } = syncBrowserPages;
|
||||
const query = { coppa: 'false' };
|
||||
const queryParam = new URLSearchParams(query);
|
||||
await page.goto(
|
||||
`${
|
||||
target.contentServerUrl
|
||||
}?context=fx_desktop_v3&service=sync&action=email&${queryParam.toString()}`,
|
||||
{ waitUntil: 'load' }
|
||||
);
|
||||
await login.setEmail(email);
|
||||
await login.submit();
|
||||
await login.setPassword(password);
|
||||
await login.confirmPassword(password);
|
||||
test('coppa disabled', async ({ target }) => {
|
||||
const { page, login, connectAnotherDevice } = syncBrowserPages;
|
||||
const query = { coppa: 'false' };
|
||||
const queryParam = new URLSearchParams(query);
|
||||
await page.goto(
|
||||
`${
|
||||
target.contentServerUrl
|
||||
}?context=fx_desktop_v3&service=sync&action=email&${queryParam.toString()}`,
|
||||
{ waitUntil: 'load' }
|
||||
);
|
||||
await login.setEmail(email);
|
||||
await login.submit();
|
||||
await login.setPassword(password);
|
||||
await login.confirmPassword(password);
|
||||
|
||||
// Age textbox is not on the page and click submit
|
||||
await login.submit();
|
||||
await login.fillOutSignUpCode(email);
|
||||
expect(await connectAnotherDevice.fxaConnected.isEnabled()).toBeTruthy();
|
||||
});
|
||||
// Age textbox is not on the page and click submit
|
||||
await login.submit();
|
||||
await login.fillOutSignUpCode(email);
|
||||
expect(await connectAnotherDevice.fxaConnected.isEnabled()).toBeTruthy();
|
||||
});
|
||||
|
||||
test('email specified by relier, invalid', async ({ target }) => {
|
||||
const { page, login } = syncBrowserPages;
|
||||
const invalidEmail = 'invalid@@';
|
||||
const query = { email: invalidEmail };
|
||||
const queryParam = new URLSearchParams(query);
|
||||
await page.goto(
|
||||
`${
|
||||
target.contentServerUrl
|
||||
}?context=fx_desktop_v3&service=sync&action=email&${queryParam.toString()}`
|
||||
);
|
||||
expect(await login.getTooltipError()).toContain('Valid email required');
|
||||
});
|
||||
test('email specified by relier, invalid', async ({ target }) => {
|
||||
const { page, login } = syncBrowserPages;
|
||||
const invalidEmail = 'invalid@@';
|
||||
const query = { email: invalidEmail };
|
||||
const queryParam = new URLSearchParams(query);
|
||||
await page.goto(
|
||||
`${
|
||||
target.contentServerUrl
|
||||
}?context=fx_desktop_v3&service=sync&action=email&${queryParam.toString()}`
|
||||
);
|
||||
expect(await login.getTooltipError()).toContain('Valid email required');
|
||||
});
|
||||
|
||||
test('email specified by relier, empty string', async ({ target }) => {
|
||||
const { page, login } = syncBrowserPages;
|
||||
const emptyEmail = '';
|
||||
const query = { email: emptyEmail };
|
||||
const queryParam = new URLSearchParams(query);
|
||||
await page.goto(
|
||||
`${
|
||||
target.contentServerUrl
|
||||
}?context=fx_desktop_v3&service=sync&action=email&${queryParam.toString()}`
|
||||
);
|
||||
expect(await login.getTooltipError()).toContain('Valid email required');
|
||||
});
|
||||
test('email specified by relier, empty string', async ({ target }) => {
|
||||
const { page, login } = syncBrowserPages;
|
||||
const emptyEmail = '';
|
||||
const query = { email: emptyEmail };
|
||||
const queryParam = new URLSearchParams(query);
|
||||
await page.goto(
|
||||
`${
|
||||
target.contentServerUrl
|
||||
}?context=fx_desktop_v3&service=sync&action=email&${queryParam.toString()}`
|
||||
);
|
||||
expect(await login.getTooltipError()).toContain('Valid email required');
|
||||
});
|
||||
|
||||
test('email specified by relier, not registered', async ({ target }) => {
|
||||
const { page, login } = syncBrowserPages;
|
||||
const query = { email };
|
||||
const queryParam = new URLSearchParams(query);
|
||||
await page.goto(
|
||||
`${
|
||||
target.contentServerUrl
|
||||
}?context=fx_desktop_v3&service=sync&action=email&${queryParam.toString()}`
|
||||
);
|
||||
test('email specified by relier, not registered', async ({ target }) => {
|
||||
const { page, login } = syncBrowserPages;
|
||||
const query = { email };
|
||||
const queryParam = new URLSearchParams(query);
|
||||
await page.goto(
|
||||
`${
|
||||
target.contentServerUrl
|
||||
}?context=fx_desktop_v3&service=sync&action=email&${queryParam.toString()}`
|
||||
);
|
||||
|
||||
// Verify user lands on the sign up password page
|
||||
expect(await login.signUpPasswordHeader()).toBe(true);
|
||||
// Verify user lands on the sign up password page
|
||||
expect(await login.signUpPasswordHeader()).toBe(true);
|
||||
|
||||
// Verify the correct email is displayed
|
||||
expect(await login.getPrefilledEmail()).toMatch(email);
|
||||
});
|
||||
// Verify the correct email is displayed
|
||||
expect(await login.getPrefilledEmail()).toMatch(email);
|
||||
});
|
||||
|
||||
test('email specified by relier, registered', async ({
|
||||
credentials,
|
||||
target,
|
||||
}) => {
|
||||
const { page, login } = syncBrowserPages;
|
||||
const query = { email: credentials.email };
|
||||
const queryParam = new URLSearchParams(query);
|
||||
await page.goto(
|
||||
`${
|
||||
target.contentServerUrl
|
||||
}?context=fx_desktop_v3&service=sync&action=email&${queryParam.toString()}`
|
||||
);
|
||||
test('email specified by relier, registered', async ({
|
||||
credentials,
|
||||
target,
|
||||
}) => {
|
||||
const { page, login } = syncBrowserPages;
|
||||
const query = { email: credentials.email };
|
||||
const queryParam = new URLSearchParams(query);
|
||||
await page.goto(
|
||||
`${
|
||||
target.contentServerUrl
|
||||
}?context=fx_desktop_v3&service=sync&action=email&${queryParam.toString()}`
|
||||
);
|
||||
|
||||
// Verify user lands on the sign in password page
|
||||
await login.waitForPasswordHeader();
|
||||
// Verify user lands on the sign in password page
|
||||
await login.waitForPasswordHeader();
|
||||
|
||||
// Verify the correct email is displayed
|
||||
expect(await login.getPrefilledEmail()).toContain(credentials.email);
|
||||
// Verify the correct email is displayed
|
||||
expect(await login.getPrefilledEmail()).toContain(credentials.email);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -12,217 +12,219 @@ let syncBrowserPages;
|
|||
|
||||
test.describe.configure({ mode: 'parallel' });
|
||||
|
||||
test.describe('Sync v3 sign up and CWTS', () => {
|
||||
test.beforeEach(async ({ target }) => {
|
||||
//Sync tests run a little slower and flake
|
||||
test.slow();
|
||||
syncBrowserPages = await newPagesForSync(target);
|
||||
const { login } = syncBrowserPages;
|
||||
email = login.createEmail('sync{id}');
|
||||
});
|
||||
|
||||
test.afterEach(async () => {
|
||||
await syncBrowserPages.browser?.close();
|
||||
});
|
||||
|
||||
test('verify with signup code and CWTS', async ({ target }) => {
|
||||
const { login, page, signinTokenCode, connectAnotherDevice } =
|
||||
syncBrowserPages;
|
||||
const query = new URLSearchParams({
|
||||
forceUA: uaStrings['desktop_firefox_71'],
|
||||
test.describe('severity-1 #smoke', () => {
|
||||
test.describe('Sync v3 sign up and CWTS', () => {
|
||||
test.beforeEach(async ({ target }) => {
|
||||
//Sync tests run a little slower and flake
|
||||
test.slow();
|
||||
syncBrowserPages = await newPagesForSync(target);
|
||||
const { login } = syncBrowserPages;
|
||||
email = login.createEmail('sync{id}');
|
||||
});
|
||||
const eventDetailStatus = createCustomEventDetail(
|
||||
FirefoxCommand.FxAStatus,
|
||||
{
|
||||
signedInUser: null,
|
||||
capabilities: {
|
||||
choose_what_to_sync: true,
|
||||
multiService: true,
|
||||
engines: ['history'],
|
||||
},
|
||||
}
|
||||
);
|
||||
const eventDetailLinkAccount = createCustomEventDetail(
|
||||
FirefoxCommand.LinkAccount,
|
||||
{
|
||||
ok: true,
|
||||
}
|
||||
);
|
||||
await page.goto(
|
||||
`${
|
||||
target.contentServerUrl
|
||||
}?context=fx_desktop_v3&service=sync&automatedBrowser=true&${query.toString()}`
|
||||
);
|
||||
await login.respondToWebChannelMessage(eventDetailStatus);
|
||||
await login.respondToWebChannelMessage(eventDetailLinkAccount);
|
||||
await login.checkWebChannelMessage('fxaccounts:fxa_status');
|
||||
await login.setEmail(email);
|
||||
await signinTokenCode.clickSubmitButton();
|
||||
await login.setPassword(password);
|
||||
await login.confirmPassword(password);
|
||||
await login.setAge('21');
|
||||
|
||||
// The CWTS form is on the same signup page
|
||||
await login.waitForCWTSEngineHeader();
|
||||
expect(await login.isCWTSEngineBookmarks()).toBe(true);
|
||||
expect(await login.isCWTSEngineHistory()).toBe(true);
|
||||
expect(await login.isCWTSEnginePasswords()).toBe(true);
|
||||
expect(await login.isCWTSEngineTabs()).toBe(true);
|
||||
expect(await login.isCWTSEnginePrefs()).toBe(true);
|
||||
expect(await login.isCWTSEngineAddresses()).toBe(false);
|
||||
|
||||
// Uncheck the passwords and history engines
|
||||
await login.uncheckCWTSEngineHistory();
|
||||
await login.uncheckCWTSEnginePasswords();
|
||||
await signinTokenCode.clickSubmitButton();
|
||||
await login.checkWebChannelMessage(FirefoxCommand.LinkAccount);
|
||||
await login.fillOutSignUpCode(email);
|
||||
expect(await connectAnotherDevice.fxaConnected.isVisible()).toBeTruthy();
|
||||
});
|
||||
|
||||
test('verify at CWTS', async ({ target }) => {
|
||||
const { login, page, signinTokenCode, connectAnotherDevice } =
|
||||
syncBrowserPages;
|
||||
const query = new URLSearchParams({
|
||||
forceUA: uaStrings['desktop_firefox_58'],
|
||||
test.afterEach(async () => {
|
||||
await syncBrowserPages.browser?.close();
|
||||
});
|
||||
const eventDetailStatus = createCustomEventDetail(
|
||||
FirefoxCommand.FxAStatus,
|
||||
{
|
||||
signedInUser: null,
|
||||
capabilities: {
|
||||
multiService: false,
|
||||
},
|
||||
}
|
||||
);
|
||||
await page.goto(
|
||||
`${
|
||||
target.contentServerUrl
|
||||
}?context=fx_desktop_v3&service=sync&automatedBrowser=true&${query.toString()}`,
|
||||
{
|
||||
waitUntil: 'load',
|
||||
}
|
||||
);
|
||||
await login.respondToWebChannelMessage(eventDetailStatus);
|
||||
await login.checkWebChannelMessage('fxaccounts:fxa_status');
|
||||
await login.setEmail(email);
|
||||
await signinTokenCode.clickSubmitButton();
|
||||
await login.setPassword(password);
|
||||
await login.confirmPassword(password);
|
||||
await login.setAge('21');
|
||||
await login.submit();
|
||||
|
||||
// Verify the CWTS page and the checkboxes
|
||||
expect(await login.isCWTSPageHeader()).toBe(true);
|
||||
expect(await login.isCWTSEngineAddresses()).toBe(false);
|
||||
expect(await login.isDoNotSync()).toBe(false);
|
||||
expect(await login.isCWTSEngineCreditCards()).toBe(false);
|
||||
await login.checkWebChannelMessage(FirefoxCommand.LinkAccount);
|
||||
await login.noSuchWebChannelMessage(FirefoxCommand.Login);
|
||||
await signinTokenCode.clickSubmitButton();
|
||||
await login.fillOutSignUpCode(email);
|
||||
await login.checkWebChannelMessage(FirefoxCommand.Login);
|
||||
expect(await connectAnotherDevice.fxaConnected.isVisible()).toBeTruthy();
|
||||
});
|
||||
test('verify with signup code and CWTS', async ({ target }) => {
|
||||
const { login, page, signinTokenCode, connectAnotherDevice } =
|
||||
syncBrowserPages;
|
||||
const query = new URLSearchParams({
|
||||
forceUA: uaStrings['desktop_firefox_71'],
|
||||
});
|
||||
const eventDetailStatus = createCustomEventDetail(
|
||||
FirefoxCommand.FxAStatus,
|
||||
{
|
||||
signedInUser: null,
|
||||
capabilities: {
|
||||
choose_what_to_sync: true,
|
||||
multiService: true,
|
||||
engines: ['history'],
|
||||
},
|
||||
}
|
||||
);
|
||||
const eventDetailLinkAccount = createCustomEventDetail(
|
||||
FirefoxCommand.LinkAccount,
|
||||
{
|
||||
ok: true,
|
||||
}
|
||||
);
|
||||
await page.goto(
|
||||
`${
|
||||
target.contentServerUrl
|
||||
}?context=fx_desktop_v3&service=sync&automatedBrowser=true&${query.toString()}`
|
||||
);
|
||||
await login.respondToWebChannelMessage(eventDetailStatus);
|
||||
await login.respondToWebChannelMessage(eventDetailLinkAccount);
|
||||
await login.checkWebChannelMessage('fxaccounts:fxa_status');
|
||||
await login.setEmail(email);
|
||||
await signinTokenCode.clickSubmitButton();
|
||||
await login.setPassword(password);
|
||||
await login.confirmPassword(password);
|
||||
await login.setAge('21');
|
||||
|
||||
test('engines not supported', async ({ target }) => {
|
||||
const { login, page, signinTokenCode } = syncBrowserPages;
|
||||
const query = new URLSearchParams({
|
||||
forceUA: uaStrings['desktop_firefox_58'],
|
||||
// The CWTS form is on the same signup page
|
||||
await login.waitForCWTSEngineHeader();
|
||||
expect(await login.isCWTSEngineBookmarks()).toBe(true);
|
||||
expect(await login.isCWTSEngineHistory()).toBe(true);
|
||||
expect(await login.isCWTSEnginePasswords()).toBe(true);
|
||||
expect(await login.isCWTSEngineTabs()).toBe(true);
|
||||
expect(await login.isCWTSEnginePrefs()).toBe(true);
|
||||
expect(await login.isCWTSEngineAddresses()).toBe(false);
|
||||
|
||||
// Uncheck the passwords and history engines
|
||||
await login.uncheckCWTSEngineHistory();
|
||||
await login.uncheckCWTSEnginePasswords();
|
||||
await signinTokenCode.clickSubmitButton();
|
||||
await login.checkWebChannelMessage(FirefoxCommand.LinkAccount);
|
||||
await login.fillOutSignUpCode(email);
|
||||
expect(await connectAnotherDevice.fxaConnected.isVisible()).toBeTruthy();
|
||||
});
|
||||
const eventDetailStatus = createCustomEventDetail(
|
||||
FirefoxCommand.FxAStatus,
|
||||
{
|
||||
signedInUser: null,
|
||||
}
|
||||
);
|
||||
await page.goto(
|
||||
`${
|
||||
target.contentServerUrl
|
||||
}?context=fx_desktop_v3&service=sync&automatedBrowser=true&${query.toString()}`
|
||||
);
|
||||
await login.respondToWebChannelMessage(eventDetailStatus);
|
||||
await login.checkWebChannelMessage('fxaccounts:fxa_status');
|
||||
await login.setEmail(email);
|
||||
await signinTokenCode.clickSubmitButton();
|
||||
await login.setPassword(password);
|
||||
await login.confirmPassword(password);
|
||||
await login.setAge('21');
|
||||
await login.submit();
|
||||
|
||||
// Verify the CWTS page and the checkboxes
|
||||
expect(await login.isCWTSPageHeader()).toBe(true);
|
||||
expect(await login.isCWTSEngineAddresses()).toBe(false);
|
||||
expect(await login.isCWTSEngineCreditCards()).toBe(false);
|
||||
});
|
||||
test('verify at CWTS', async ({ target }) => {
|
||||
const { login, page, signinTokenCode, connectAnotherDevice } =
|
||||
syncBrowserPages;
|
||||
const query = new URLSearchParams({
|
||||
forceUA: uaStrings['desktop_firefox_58'],
|
||||
});
|
||||
const eventDetailStatus = createCustomEventDetail(
|
||||
FirefoxCommand.FxAStatus,
|
||||
{
|
||||
signedInUser: null,
|
||||
capabilities: {
|
||||
multiService: false,
|
||||
},
|
||||
}
|
||||
);
|
||||
await page.goto(
|
||||
`${
|
||||
target.contentServerUrl
|
||||
}?context=fx_desktop_v3&service=sync&automatedBrowser=true&${query.toString()}`,
|
||||
{
|
||||
waitUntil: 'load',
|
||||
}
|
||||
);
|
||||
await login.respondToWebChannelMessage(eventDetailStatus);
|
||||
await login.checkWebChannelMessage('fxaccounts:fxa_status');
|
||||
await login.setEmail(email);
|
||||
await signinTokenCode.clickSubmitButton();
|
||||
await login.setPassword(password);
|
||||
await login.confirmPassword(password);
|
||||
await login.setAge('21');
|
||||
await login.submit();
|
||||
|
||||
test('neither `creditcards` nor `addresses` supported', async ({
|
||||
target,
|
||||
}) => {
|
||||
const { login, page, signinTokenCode } = syncBrowserPages;
|
||||
const query = new URLSearchParams({
|
||||
forceUA: uaStrings['desktop_firefox_58'],
|
||||
// Verify the CWTS page and the checkboxes
|
||||
expect(await login.isCWTSPageHeader()).toBe(true);
|
||||
expect(await login.isCWTSEngineAddresses()).toBe(false);
|
||||
expect(await login.isDoNotSync()).toBe(false);
|
||||
expect(await login.isCWTSEngineCreditCards()).toBe(false);
|
||||
await login.checkWebChannelMessage(FirefoxCommand.LinkAccount);
|
||||
await login.noSuchWebChannelMessage(FirefoxCommand.Login);
|
||||
await signinTokenCode.clickSubmitButton();
|
||||
await login.fillOutSignUpCode(email);
|
||||
await login.checkWebChannelMessage(FirefoxCommand.Login);
|
||||
expect(await connectAnotherDevice.fxaConnected.isVisible()).toBeTruthy();
|
||||
});
|
||||
const eventDetailStatus = createCustomEventDetail(
|
||||
FirefoxCommand.FxAStatus,
|
||||
{
|
||||
capabilities: {
|
||||
engines: [],
|
||||
},
|
||||
signedInUser: null,
|
||||
}
|
||||
);
|
||||
await page.goto(
|
||||
`${
|
||||
target.contentServerUrl
|
||||
}?context=fx_desktop_v3&service=sync&automatedBrowser=true&${query.toString()}`
|
||||
);
|
||||
await login.respondToWebChannelMessage(eventDetailStatus);
|
||||
await login.checkWebChannelMessage('fxaccounts:fxa_status');
|
||||
await login.setEmail(email);
|
||||
await signinTokenCode.clickSubmitButton();
|
||||
await login.setPassword(password);
|
||||
await login.confirmPassword(password);
|
||||
await login.setAge('21');
|
||||
await login.submit();
|
||||
|
||||
// Verify the CWTS page and the checkboxes
|
||||
expect(await login.isCWTSPageHeader()).toBe(true);
|
||||
expect(await login.isCWTSEngineAddresses()).toBe(false);
|
||||
expect(await login.isCWTSEngineCreditCards()).toBe(false);
|
||||
});
|
||||
test('engines not supported', async ({ target }) => {
|
||||
const { login, page, signinTokenCode } = syncBrowserPages;
|
||||
const query = new URLSearchParams({
|
||||
forceUA: uaStrings['desktop_firefox_58'],
|
||||
});
|
||||
const eventDetailStatus = createCustomEventDetail(
|
||||
FirefoxCommand.FxAStatus,
|
||||
{
|
||||
signedInUser: null,
|
||||
}
|
||||
);
|
||||
await page.goto(
|
||||
`${
|
||||
target.contentServerUrl
|
||||
}?context=fx_desktop_v3&service=sync&automatedBrowser=true&${query.toString()}`
|
||||
);
|
||||
await login.respondToWebChannelMessage(eventDetailStatus);
|
||||
await login.checkWebChannelMessage('fxaccounts:fxa_status');
|
||||
await login.setEmail(email);
|
||||
await signinTokenCode.clickSubmitButton();
|
||||
await login.setPassword(password);
|
||||
await login.confirmPassword(password);
|
||||
await login.setAge('21');
|
||||
await login.submit();
|
||||
|
||||
test('`creditcards` and `addresses` supported', async ({ target }) => {
|
||||
const { login, page, signinTokenCode } = syncBrowserPages;
|
||||
const query = new URLSearchParams({
|
||||
forceUA: uaStrings['desktop_firefox_58'],
|
||||
// Verify the CWTS page and the checkboxes
|
||||
expect(await login.isCWTSPageHeader()).toBe(true);
|
||||
expect(await login.isCWTSEngineAddresses()).toBe(false);
|
||||
expect(await login.isCWTSEngineCreditCards()).toBe(false);
|
||||
});
|
||||
const eventDetailStatus = createCustomEventDetail(
|
||||
FirefoxCommand.FxAStatus,
|
||||
{
|
||||
capabilities: {
|
||||
engines: ['creditcards', 'addresses'],
|
||||
},
|
||||
signedInUser: null,
|
||||
}
|
||||
);
|
||||
await page.goto(
|
||||
`${
|
||||
target.contentServerUrl
|
||||
}?context=fx_desktop_v3&service=sync&automatedBrowser=true&${query.toString()}`
|
||||
);
|
||||
await login.respondToWebChannelMessage(eventDetailStatus);
|
||||
await login.checkWebChannelMessage('fxaccounts:fxa_status');
|
||||
await login.setEmail(email);
|
||||
await signinTokenCode.clickSubmitButton();
|
||||
await login.setPassword(password);
|
||||
await login.confirmPassword(password);
|
||||
await login.setAge('21');
|
||||
await login.submit();
|
||||
|
||||
// Verify the CWTS page and the checkboxes
|
||||
expect(await login.isCWTSPageHeader()).toBe(true);
|
||||
expect(await login.isCWTSEngineAddresses()).toBe(true);
|
||||
expect(await login.isCWTSEngineCreditCards()).toBe(true);
|
||||
test('neither `creditcards` nor `addresses` supported', async ({
|
||||
target,
|
||||
}) => {
|
||||
const { login, page, signinTokenCode } = syncBrowserPages;
|
||||
const query = new URLSearchParams({
|
||||
forceUA: uaStrings['desktop_firefox_58'],
|
||||
});
|
||||
const eventDetailStatus = createCustomEventDetail(
|
||||
FirefoxCommand.FxAStatus,
|
||||
{
|
||||
capabilities: {
|
||||
engines: [],
|
||||
},
|
||||
signedInUser: null,
|
||||
}
|
||||
);
|
||||
await page.goto(
|
||||
`${
|
||||
target.contentServerUrl
|
||||
}?context=fx_desktop_v3&service=sync&automatedBrowser=true&${query.toString()}`
|
||||
);
|
||||
await login.respondToWebChannelMessage(eventDetailStatus);
|
||||
await login.checkWebChannelMessage('fxaccounts:fxa_status');
|
||||
await login.setEmail(email);
|
||||
await signinTokenCode.clickSubmitButton();
|
||||
await login.setPassword(password);
|
||||
await login.confirmPassword(password);
|
||||
await login.setAge('21');
|
||||
await login.submit();
|
||||
|
||||
// Verify the CWTS page and the checkboxes
|
||||
expect(await login.isCWTSPageHeader()).toBe(true);
|
||||
expect(await login.isCWTSEngineAddresses()).toBe(false);
|
||||
expect(await login.isCWTSEngineCreditCards()).toBe(false);
|
||||
});
|
||||
|
||||
test('`creditcards` and `addresses` supported', async ({ target }) => {
|
||||
const { login, page, signinTokenCode } = syncBrowserPages;
|
||||
const query = new URLSearchParams({
|
||||
forceUA: uaStrings['desktop_firefox_58'],
|
||||
});
|
||||
const eventDetailStatus = createCustomEventDetail(
|
||||
FirefoxCommand.FxAStatus,
|
||||
{
|
||||
capabilities: {
|
||||
engines: ['creditcards', 'addresses'],
|
||||
},
|
||||
signedInUser: null,
|
||||
}
|
||||
);
|
||||
await page.goto(
|
||||
`${
|
||||
target.contentServerUrl
|
||||
}?context=fx_desktop_v3&service=sync&automatedBrowser=true&${query.toString()}`
|
||||
);
|
||||
await login.respondToWebChannelMessage(eventDetailStatus);
|
||||
await login.checkWebChannelMessage('fxaccounts:fxa_status');
|
||||
await login.setEmail(email);
|
||||
await signinTokenCode.clickSubmitButton();
|
||||
await login.setPassword(password);
|
||||
await login.confirmPassword(password);
|
||||
await login.setAge('21');
|
||||
await login.submit();
|
||||
|
||||
// Verify the CWTS page and the checkboxes
|
||||
expect(await login.isCWTSPageHeader()).toBe(true);
|
||||
expect(await login.isCWTSEngineAddresses()).toBe(true);
|
||||
expect(await login.isCWTSEngineCreditCards()).toBe(true);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -8,111 +8,113 @@ let email;
|
|||
let email2;
|
||||
let syncBrowserPages;
|
||||
|
||||
test.describe('sync signin cached', () => {
|
||||
test.beforeEach(async ({ target }) => {
|
||||
test.slow();//This test has steps for email rendering that runs slow on stage
|
||||
syncBrowserPages = await newPagesForSync(target);
|
||||
const { login } = syncBrowserPages;
|
||||
email = login.createEmail('sync{id}');
|
||||
email2 = login.createEmail();
|
||||
await target.auth.signUp(email, password, {
|
||||
lang: 'en',
|
||||
preVerified: 'true',
|
||||
test.describe('severity-2 #smoke', () => {
|
||||
test.describe('sync signin cached', () => {
|
||||
test.beforeEach(async ({ target }) => {
|
||||
test.slow(); //This test has steps for email rendering that runs slow on stage
|
||||
syncBrowserPages = await newPagesForSync(target);
|
||||
const { login } = syncBrowserPages;
|
||||
email = login.createEmail('sync{id}');
|
||||
email2 = login.createEmail();
|
||||
await target.auth.signUp(email, password, {
|
||||
lang: 'en',
|
||||
preVerified: 'true',
|
||||
});
|
||||
await target.auth.signUp(email2, password, {
|
||||
lang: 'en',
|
||||
preVerified: 'true',
|
||||
});
|
||||
});
|
||||
await target.auth.signUp(email2, password, {
|
||||
lang: 'en',
|
||||
preVerified: 'true',
|
||||
});
|
||||
});
|
||||
|
||||
test.afterEach(async ({ target }) => {
|
||||
test.slow();//The cleanup was timing out and exceeding 3000ms
|
||||
await syncBrowserPages.browser?.close();
|
||||
const emails = [email, email2];
|
||||
for (const email of emails) {
|
||||
if (email) {
|
||||
try {
|
||||
await target.auth.accountDestroy(email, password);
|
||||
} catch (e) {
|
||||
// Handle any errors if needed
|
||||
test.afterEach(async ({ target }) => {
|
||||
test.slow(); //The cleanup was timing out and exceeding 3000ms
|
||||
await syncBrowserPages.browser?.close();
|
||||
const emails = [email, email2];
|
||||
for (const email of emails) {
|
||||
if (email) {
|
||||
try {
|
||||
await target.auth.accountDestroy(email, password);
|
||||
} catch (e) {
|
||||
// Handle any errors if needed
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
test('sign in on desktop then specify a different email on query parameter continues to cache desktop signin', async ({
|
||||
target,
|
||||
}) => {
|
||||
const { page, login, connectAnotherDevice } = syncBrowserPages;
|
||||
await page.goto(
|
||||
`${target.contentServerUrl}?context=fx_desktop_v3&service=sync`
|
||||
);
|
||||
await login.fillOutEmailFirstSignIn(email, password);
|
||||
|
||||
//Verify sign up code header is visible
|
||||
await login.waitForSignInCodeHeader();
|
||||
|
||||
const query = { email: email2 };
|
||||
const queryParam = new URLSearchParams(query);
|
||||
await page.goto(
|
||||
`${
|
||||
target.contentServerUrl
|
||||
}?context=fx_desktop_v3&service=sync&action=email&${queryParam.toString()}`
|
||||
);
|
||||
|
||||
//Check prefilled email
|
||||
expect(await login.getPrefilledEmail()).toContain(email2);
|
||||
await login.setPassword(password);
|
||||
await login.clickSubmit();
|
||||
await connectAnotherDevice.clickNotNow();
|
||||
|
||||
//Verify logged in on Settings page
|
||||
expect(await login.isUserLoggedIn()).toBe(true);
|
||||
|
||||
//Reset prefill and context
|
||||
await login.clearSessionStorage();
|
||||
|
||||
//Testing to make sure cached signin comes back after a refresh
|
||||
await page.goto(target.contentServerUrl, {
|
||||
waitUntil: 'load',
|
||||
});
|
||||
expect(await login.getPrefilledEmail()).toContain(email);
|
||||
await login.useDifferentAccountLink();
|
||||
await login.waitForEmailHeader();
|
||||
});
|
||||
|
||||
test('sign in with desktop context then no context, desktop credentials should persist', async ({
|
||||
target,
|
||||
}) => {
|
||||
const { page, login } = syncBrowserPages;
|
||||
await page.goto(
|
||||
`${target.contentServerUrl}?context=fx_desktop_v3&service=sync`
|
||||
);
|
||||
await login.fillOutEmailFirstSignIn(email, password);
|
||||
test('sign in on desktop then specify a different email on query parameter continues to cache desktop signin', async ({
|
||||
target,
|
||||
}) => {
|
||||
const { page, login, connectAnotherDevice } = syncBrowserPages;
|
||||
await page.goto(
|
||||
`${target.contentServerUrl}?context=fx_desktop_v3&service=sync`
|
||||
);
|
||||
await login.fillOutEmailFirstSignIn(email, password);
|
||||
|
||||
//Verify sign up code header is visible
|
||||
await login.waitForSignInCodeHeader();
|
||||
//Verify sign up code header is visible
|
||||
await login.waitForSignInCodeHeader();
|
||||
|
||||
await page.goto(target.contentServerUrl, {
|
||||
waitUntil: 'load',
|
||||
const query = { email: email2 };
|
||||
const queryParam = new URLSearchParams(query);
|
||||
await page.goto(
|
||||
`${
|
||||
target.contentServerUrl
|
||||
}?context=fx_desktop_v3&service=sync&action=email&${queryParam.toString()}`
|
||||
);
|
||||
|
||||
//Check prefilled email
|
||||
expect(await login.getPrefilledEmail()).toContain(email2);
|
||||
await login.setPassword(password);
|
||||
await login.clickSubmit();
|
||||
await connectAnotherDevice.clickNotNow();
|
||||
|
||||
//Verify logged in on Settings page
|
||||
expect(await login.isUserLoggedIn()).toBe(true);
|
||||
|
||||
//Reset prefill and context
|
||||
await login.clearSessionStorage();
|
||||
|
||||
//Testing to make sure cached signin comes back after a refresh
|
||||
await page.goto(target.contentServerUrl, {
|
||||
waitUntil: 'load',
|
||||
});
|
||||
expect(await login.getPrefilledEmail()).toContain(email);
|
||||
await login.useDifferentAccountLink();
|
||||
await login.waitForEmailHeader();
|
||||
});
|
||||
expect(await login.getPrefilledEmail()).toContain(email);
|
||||
await login.useDifferentAccountLink();
|
||||
await login.waitForEmailHeader();
|
||||
await login.fillOutEmailFirstSignIn(email2, password);
|
||||
|
||||
//Verify logged in on Settings page
|
||||
expect(await login.isUserLoggedIn()).toBe(true);
|
||||
test('sign in with desktop context then no context, desktop credentials should persist', async ({
|
||||
target,
|
||||
}) => {
|
||||
const { page, login } = syncBrowserPages;
|
||||
await page.goto(
|
||||
`${target.contentServerUrl}?context=fx_desktop_v3&service=sync`
|
||||
);
|
||||
await login.fillOutEmailFirstSignIn(email, password);
|
||||
|
||||
//Reset prefill and context
|
||||
await login.clearSessionStorage();
|
||||
//Verify sign up code header is visible
|
||||
await login.waitForSignInCodeHeader();
|
||||
|
||||
//Testing to make sure cached signin comes back after a refresh
|
||||
await page.goto(target.contentServerUrl, {
|
||||
waitUntil: 'load',
|
||||
await page.goto(target.contentServerUrl, {
|
||||
waitUntil: 'load',
|
||||
});
|
||||
expect(await login.getPrefilledEmail()).toContain(email);
|
||||
await login.useDifferentAccountLink();
|
||||
await login.waitForEmailHeader();
|
||||
await login.fillOutEmailFirstSignIn(email2, password);
|
||||
|
||||
//Verify logged in on Settings page
|
||||
expect(await login.isUserLoggedIn()).toBe(true);
|
||||
|
||||
//Reset prefill and context
|
||||
await login.clearSessionStorage();
|
||||
|
||||
//Testing to make sure cached signin comes back after a refresh
|
||||
await page.goto(target.contentServerUrl, {
|
||||
waitUntil: 'load',
|
||||
});
|
||||
expect(await login.getPrefilledEmail()).toContain(email);
|
||||
await login.useDifferentAccountLink();
|
||||
await login.waitForEmailHeader();
|
||||
});
|
||||
expect(await login.getPrefilledEmail()).toContain(email);
|
||||
await login.useDifferentAccountLink();
|
||||
await login.waitForEmailHeader();
|
||||
});
|
||||
});
|
||||
|
|
|
@ -5,45 +5,59 @@
|
|||
import { test } from '../../lib/fixtures/standard';
|
||||
import { authenticator } from 'otplib';
|
||||
|
||||
const GOOGLE_TEST_EMAIL = process.env.GOOGLE_TEST_EMAIL || 'fxalive2022@gmail.com';
|
||||
const GOOGLE_TEST_EMAIL =
|
||||
process.env.GOOGLE_TEST_EMAIL || 'fxalive2022@gmail.com';
|
||||
const GOOGLE_TEST_PASSWORD = process.env.GOOGLE_TEST_PASSWORD;
|
||||
const GOOGLE_TEST_2FA_SECRET = process.env.GOOGLE_TEST_2FA_SECRET;
|
||||
|
||||
test.describe('third party auth', () => {
|
||||
test('Google signin to settings', async ({
|
||||
target,
|
||||
pages: { login, page },
|
||||
}) => {
|
||||
const shouldSkip = !GOOGLE_TEST_EMAIL || !GOOGLE_TEST_PASSWORD || !GOOGLE_TEST_2FA_SECRET;
|
||||
test.skip(shouldSkip, 'Please contact FxA admin to get credentials for Google account');
|
||||
test.slow();
|
||||
await page.goto(
|
||||
target.contentServerUrl + '?forceExperiment=thirdPartyAuth&forceExperimentGroup=treatment',
|
||||
{ waitUntil: 'load' },
|
||||
);
|
||||
test.describe('severity-1 #smoke', () => {
|
||||
test.describe('third party auth', () => {
|
||||
test('Google signin to settings', async ({
|
||||
target,
|
||||
pages: { login, page },
|
||||
}) => {
|
||||
const shouldSkip =
|
||||
!GOOGLE_TEST_EMAIL || !GOOGLE_TEST_PASSWORD || !GOOGLE_TEST_2FA_SECRET;
|
||||
test.skip(
|
||||
shouldSkip,
|
||||
'Please contact FxA admin to get credentials for Google account'
|
||||
);
|
||||
test.slow();
|
||||
await page.goto(
|
||||
target.contentServerUrl +
|
||||
'?forceExperiment=thirdPartyAuth&forceExperimentGroup=treatment',
|
||||
{ waitUntil: 'load' }
|
||||
);
|
||||
|
||||
await login.clickContinueWithGoogle();
|
||||
await login.clickContinueWithGoogle();
|
||||
|
||||
await page.locator('input[type="email"]').fill(GOOGLE_TEST_EMAIL);
|
||||
await page.getByText('Next').click();
|
||||
await page.waitForURL(/v3\/signin\/challenge\/pwd/);
|
||||
await page.locator('input[type="email"]').fill(GOOGLE_TEST_EMAIL);
|
||||
await page.getByText('Next').click();
|
||||
await page.waitForURL(/v3\/signin\/challenge\/pwd/);
|
||||
|
||||
await page.locator('input[type="password"]').fill(GOOGLE_TEST_PASSWORD);
|
||||
await page.getByText('Next').click();
|
||||
await page.locator('input[type="password"]').fill(GOOGLE_TEST_PASSWORD);
|
||||
await page.getByText('Next').click();
|
||||
|
||||
let token = authenticator.generate(GOOGLE_TEST_2FA_SECRET);
|
||||
await page.locator('#totpPin').fill(token);
|
||||
await page.locator('#totpNext').getByRole('button', { name: 'Next' }).click();
|
||||
let token = authenticator.generate(GOOGLE_TEST_2FA_SECRET);
|
||||
await page.locator('#totpPin').fill(token);
|
||||
await page
|
||||
.locator('#totpNext')
|
||||
.getByRole('button', { name: 'Next' })
|
||||
.click();
|
||||
|
||||
const invalidCodeLocator = await page.getByText('Wrong code. Try again.');
|
||||
if (await invalidCodeLocator.isVisible()) {
|
||||
// Per chance the 2FA code expired, wait few seconds and try a new code
|
||||
await page.waitForTimeout(5000);
|
||||
token = authenticator.generate(GOOGLE_TEST_2FA_SECRET);
|
||||
await page.locator('#totpPin').fill(token);
|
||||
await page.locator('#totpNext').getByRole('button', { name: 'Next' }).click();
|
||||
}
|
||||
const invalidCodeLocator = await page.getByText('Wrong code. Try again.');
|
||||
if (await invalidCodeLocator.isVisible()) {
|
||||
// Per chance the 2FA code expired, wait few seconds and try a new code
|
||||
await page.waitForTimeout(5000);
|
||||
token = authenticator.generate(GOOGLE_TEST_2FA_SECRET);
|
||||
await page.locator('#totpPin').fill(token);
|
||||
await page
|
||||
.locator('#totpNext')
|
||||
.getByRole('button', { name: 'Next' })
|
||||
.click();
|
||||
}
|
||||
|
||||
await page.waitForURL(/settings/);
|
||||
});
|
||||
await page.waitForURL(/settings/);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
Загрузка…
Ссылка в новой задаче