This commit is contained in:
mozrokafor 2023-03-30 10:17:57 -04:00 коммит произвёл John Whitlock
Родитель 087121263a
Коммит dcdbfed8c3
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 082C735D154FB750
6 изменённых файлов: 102 добавлений и 90 удалений

1
.gitignore поставляемый
Просмотреть файл

@ -16,3 +16,4 @@ junit.xml
state.json
har/
allure-results/
allure-report/

Просмотреть файл

@ -27,6 +27,7 @@ export class DashboardPage {
readonly emailMasksUsedAmount: Locator
readonly maskCard: string
readonly maskCardExpanded: Locator
readonly maskCardExpandButton: Locator
readonly maskCardHeader: Locator
readonly maskCardForwardEmail: Locator
readonly maskCardCreatedDate: Locator
@ -59,7 +60,7 @@ export class DashboardPage {
this.toastCloseButton = '//div[starts-with(@class, "Layout_close")]'
this.signOutButton = page.locator('button:has-text("Sign Out")').first()
this.signOutToastAlert = page.locator('//div[@class="Toastify__toast-body"]')
// dashboard elements
this.upgradeNowButton = page.locator('a:has-text("Upgrade Now")')
this.upgradeButton = page.locator('a:has-text("Upgrade")').first()
@ -67,7 +68,7 @@ export class DashboardPage {
this.dashboardPageWithoutHeader = page.locator('//main[starts-with(@class, "profile_profile-wrapper")]')
this.emailsForwardedAmount = page.locator('(//dd[starts-with(@class, "profile_value")])[3]')
this.emailsBlockedAmount = page.locator('(//dd[starts-with(@class, "profile_value")])[2]')
this.emailMasksUsedAmount = page.locator('(//dd[starts-with(@class, "profile_value")])[1]')
this.emailMasksUsedAmount = page.locator('(//dd[starts-with(@class, "profile_value")])[1]')
this.generateNewMaskButton = page.locator('button:has-text("Generate new mask")')
this.maxMaskLimitButton = page.locator('//div[starts-with(@class, "AliasList_controls")]//a[starts-with(@class, "Button_button")]')
this.bottomUgradeBanner = page.locator('//div[starts-with(@class, "profile_bottom-banner-wrapper")]')
@ -76,25 +77,26 @@ export class DashboardPage {
this.dashBoardWithoutMasksEmail = page.locator('//section[starts-with(@class, "profile_no-premium-header")]')
// mask card elements
this.maskCard = '//div[starts-with(@class, "Alias_alias-card")]'
this.maskCardExpanded = page.locator('//ul/li//div[contains(@class, "Alias_is-expanded")]').first()
this.maskCardHeader = page.locator('//*[starts-with(@class, "Alias_main-data")]')
this.maskCardGeneratedEmail = page.locator('(//span[starts-with(@class, "Alias_copy-button")]/button)[1]')
this.maskCard = '//div[starts-with(@class, "MaskCard_card")]'
this.maskCardExpanded = page.locator('//button[starts-with(@class, "MaskCard_expand")]')
this.maskCardExpandButton = page.locator('//button[starts-with(@class, "MaskCard_expand")]')
this.maskCardHeader = page.locator('//div[starts-with(@class, "MaskCard_summary")]')
this.maskCardGeneratedEmail = page.locator('//button[starts-with(@class, "MaskCard_copy")]/samp').first()
this.maskCardForwardEmail = page.locator('//div[starts-with(@class, "Alias_forward-target")]')
this.maskCardCreatedDate = page.locator('//div[starts-with(@class, "Alias_date-created")]')
this.maskCardForwardedAmount = page.locator('(//span[contains(@class, "Alias_forwarded-stat")])[1]')
this.maskCardForwardedAmount = page.locator('//div[contains(@class, "MaskCard_forwarded")]/dd').first()
this.maskCardRepliesAmount = page.locator('(//span[contains(@class, "Alias_blocked-stat")])[2]')
this.maskCardBlockedAmount = page.locator('(//span[contains(@class, "Alias_blocked-stat")])[1]')
this.maskCardDeleteButton = page.locator('(//button[starts-with(@class, "AliasDeletionButton_deletion")])[1]')
this.maskCardCancelButton = page.locator('(//button[starts-with(@class, "AliasDeletionButton_cancel-button")])[1]')
this.maskCardDeleteButton = page.locator('button:has-text("Delete")')
this.maskCardCancelButton = page.locator('button:has-text("Cancel")')
this.maskCardDeleteDialogModal = page.locator('//div[starts-with(@class, "AliasDeletionButton_dialog-wrapper")]')
this.maskCardDeleteDialogModalEmailString = page.locator('//div[starts-with(@class, "AliasDeletionButton_dialog-wrapper")]//strong')
this.maskCardDeleteDialogModalGeneratedEmail = page.locator('//div[starts-with(@class, "AliasDeletionButton_dialog-wrapper")]//samp')
this.maskCardDeleteConfirmationCheckbox = page.locator('#confirmDeletion')
this.maskCardFinalDeleteButton = page.locator('//button[contains(@class, "Button_is-destructive")]')
}
}
async open() {
async open() {
await this.page.goto('/accounts/profile/');
}
@ -103,15 +105,15 @@ export class DashboardPage {
if(numberOfMasks === 0){
return
}
// generate a new mask and confirm
await this.generateNewMaskButton.click()
await this.page.waitForSelector(this.maskCard, { timeout: 3000 })
// randomize between 1.5-2.5 secs between each generate to deal with issue of multiple quick clicks
await this.page.waitForTimeout((Math.random() * 2500) + 1500)
await this.generateMask(numberOfMasks - 1)
}
}
async upgrade(){
await Promise.all([
@ -136,7 +138,7 @@ export class DashboardPage {
}
}
async maybeDeleteMasks(clearAll = true, numberOfMasks = 1){
async maybeDeleteMasks(clearAll = true, numberOfMasks = 1){
let isExpanded = false
// check number of masks available
@ -146,35 +148,33 @@ export class DashboardPage {
// if clear all, check if there's an expanded mask card
if(clearAll){
try {
await this.page.waitForSelector(this.maskCard, { timeout: 3000 })
try {
await this.page.waitForSelector(this.maskCard, { timeout: 3000 })
numberOfMasks = await this.page.locator(this.maskCard).count()
} catch (error) {
console.error('There are no masks to delete')
return
}
try {
isExpanded = await this.maskCardExpanded.isVisible()
} catch {}
}
// locate mask expand button only if mask is not already expanded
if(numberOfMasks && !isExpanded){
try {
const anchorLocator = `(//div[starts-with(@class, "Alias_expand-toggle")])[${numberOfMasks}]/button`
await this.page.waitForSelector(anchorLocator, { timeout: 3000 })
await this.page.locator(anchorLocator).click()
isExpanded = await this.page.getByRole('button', { expanded: true }).first().isVisible()
} catch {}
}
// delete flow
// locate mask expand button only if mask is not already expanded
if(numberOfMasks && !isExpanded){
try {
await this.maskCardExpanded.first().click()
} catch {}
}
// delete flow
if(numberOfMasks){
const currentMaskCardDeleteButton = this.page.locator(`(//button[starts-with(@class, "AliasDeletionButton_deletion")])[${numberOfMasks}]`)
const currentMaskCardDeleteButton = this.page.locator('button:has-text("Delete")').first()
await currentMaskCardDeleteButton.click()
await this.maskCardDeleteConfirmationCheckbox.click()
await this.maskCardFinalDeleteButton.click()
}
await this.maskCardFinalDeleteButton.click()
}
// wait for 500 ms and run flow again with the next masks
await this.page.waitForTimeout(500)
@ -186,34 +186,30 @@ export class DashboardPage {
await this.open()
await checkAuthState(this.page)
await this.maybeDeleteMasks()
// create mask and use generated mask email to test email forwarding feature
await this.generateMask(1)
const generatedMaskEmail = await this.maskCardGeneratedEmail.textContent()
await this.page.goto("https://monitor.firefox.com/")
const checkForBreachesEmailInput = this.page.locator('#scan-email').first();
const newsLetterCheckBox = '.create-fxa-checkbox-checkmark';
const CheckForBreachesButton = this.page.locator('#scan-user-email [data-entrypoint="fx-monitor-check-for-breaches-blue-btn"]').first();
await checkForBreachesEmailInput.fill(generatedMaskEmail as string)
await this.page.check(newsLetterCheckBox)
await Promise.all([
this.page.waitForNavigation(),
CheckForBreachesButton.click()
]);
await this.page.goto("https://monitor.firefox.com/", { waitUntil: 'networkidle' })
const monitorLoginButton = this.page.getByRole('link', { name: 'Get started' })
await monitorLoginButton.first().click()
const monitorEmailInput = this.page.locator('.input-text')
const submitButton = this.page.locator('#submit-btn')
await monitorEmailInput.fill(generatedMaskEmail as string)
await submitButton.click()
const passwordInputField = this.page.locator('#password');
const passwordConfirmInputField = this.page.locator('#vpassword');
const ageInputField = this.page.locator('#age');
const createAccountButton = this.page.locator('#submit-btn');
await passwordInputField.fill(process.env.E2E_TEST_ACCOUNT_PASSWORD as string);
await passwordConfirmInputField.fill(process.env.E2E_TEST_ACCOUNT_PASSWORD as string);
await ageInputField.fill('31');
await createAccountButton.click()
// wait for email to be forward to restmail
await getVerificationCode(process.env.E2E_TEST_ACCOUNT_FREE as string, this.page)
}
@ -227,12 +223,17 @@ export class DashboardPage {
await this.FAQButton.click()
await this.homeButton.click()
// check if card is expanded
if(!(await this.page.getByRole('button', { expanded: true }).first().isVisible())){
await this.maskCardExpanded.first().click()
}
// check the forward emails count, if not 0, return the current value
const forwardCount = await this.maskCardForwardedAmount.textContent()
if(forwardCount !== "0Forwarded"){
if(forwardCount !== "0"){
return forwardCount;
}
await this.page.waitForTimeout(1000)
return this.checkForwardedEmailCount(attempts - 1)
}

Просмотреть файл

@ -1,17 +1,16 @@
import test, { expect } from '../fixtures/basePages'
import { checkAuthState } from '../e2eTestUtils/helpers';
test.describe.configure({ mode: 'parallel' });
test.skip(({ browserName }) => browserName !== 'firefox', 'firefox only e2e!');
test.describe('Relay e2e function email forwarding', () => {
test.describe('Relay e2e function email forwarding', () => {
// use stored authenticated state
test.use({ storageState: 'state.json' })
test.beforeEach(async ({ dashboardPage }) => {
test.beforeEach(async ({ dashboardPage }) => {
await dashboardPage.sendMaskEmail()
});
test('Check that the user can use the masks on websites and receive emails sent to the masks, C1553068, C1553065, C1811801', async ({
test('Check that the user can use the masks on websites and receive emails sent to the masks, C1553068, C1553065, C1811801', async ({
dashboardPage,
page
}) => {
@ -19,27 +18,25 @@ test.describe('Relay e2e function email forwarding', () => {
// the signup confirmation email show up in the forwarded email count.
// This is a pretty slow process:
test.slow()
await dashboardPage.open()
await checkAuthState(page)
const forwardedEmailCount = await dashboardPage.checkForwardedEmailCount()
expect(forwardedEmailCount).toEqual('1Forwarded')
await expect(async () => {
await dashboardPage.open()
await checkAuthState(page)
const forwardedEmailCount = await dashboardPage.checkForwardedEmailCount()
await dashboardPage.userMenuButton.click()
await dashboardPage.signOutButton.click()
expect(await dashboardPage.signOutToastAlert.textContent()).toContain('You have signed out.')
expect(forwardedEmailCount).toEqual('1')
}).toPass()
})
})
test.fixme('Relay e2e auth flows', () => {
// pricing table is being updated -- will update this test afterwords
test.beforeEach(async ({ landingPage }) => {
await landingPage.open()
await landingPage.open()
});
test('Verify that the "Sign Up" button works correctly, C1818792', async ({
test('Verify that the "Sign Up" button works correctly, C1818792', async ({
landingPage
}) => {
}) => {
await landingPage.selectPricingPlanSignUp()
// verify redirect to subscription page

Просмотреть файл

@ -9,20 +9,28 @@ test.describe('Free - General Functionalities, Desktop', () => {
await checkAuthState(page)
await dashboardPage.maybeDeleteMasks()
});
test('Check the free user can only create 5 masks, C1553067', async ({ dashboardPage }) => {
test('Check the free user can only create 5 masks, C1553067', async ({ dashboardPage, page }) => {
// Generating five masks takes a while:
test.slow()
await dashboardPage.generateMask(5)
await expect(async () => {
await dashboardPage.generateMask(5)
expect(await page.locator(dashboardPage.maskCard).count() === 5)
}).toPass()
// After five times, the button becomes greyed-out and the user cannot add other masks anymore (TODO: for a free user from a country where Premium is NOT available).
expect(await dashboardPage.maxMaskLimitButton.textContent()).toContain('Get unlimited email masks')
})
test('Check that when generating a new mask, its card is automatically opened, C1686210, C1553075, C1553064', async ({ dashboardPage }) => {
await dashboardPage.generateMask(1)
await expect(dashboardPage.maskCardExpanded).toBeVisible()
test('Check that when generating a new mask, its card is automatically opened, C1686210, C1553075, C1553064', async ({ dashboardPage, page }) => {
await expect(async () => {
await dashboardPage.generateMask(1)
expect(await page.locator(dashboardPage.maskCard).count() === 1)
}).toPass()
await expect(page.locator(dashboardPage.maskCard)).toBeInViewport()
await expect(dashboardPage.maskCardExpandButton).toHaveAttribute("aria-expanded", "true")
expect(await dashboardPage.maskCardHeader.textContent()).toContain(ENV_DOMAINS[process.env.E2E_TEST_ENV as string])
})
})
@ -34,7 +42,7 @@ test.describe('Free - General Functionalities, Desktop - Visual Regression', ()
await dashboardPage.open()
await checkAuthState(page)
await dashboardPage.maybeDeleteMasks()
});
});
test('Verify that the Header is displayed correctly for a Free user that is logged in, C1812639', async ({ dashboardPage }) => {
await dashboardPage.maybeCloseToaster()
@ -44,7 +52,7 @@ test.describe('Free - General Functionalities, Desktop - Visual Regression', ()
);
})
test.fixme('Verify that the "Profile" button and its options work correctly, C1812641', async ({ dashboardPage }) => {
test.fixme('Verify that the "Profile" button and its options work correctly, C1812641', async ({ dashboardPage }) => {
await dashboardPage.relayExtensionBanner.scrollIntoViewIfNeeded()
await expect(dashboardPage.relayExtensionBanner).toHaveScreenshot(
`${process.env.E2E_TEST_ENV}-relayExtensionBanner.png`,
@ -59,25 +67,30 @@ test.describe('Free - General Functionalities, Desktop - Visual Regression', ()
})
test('Verify that opened mask cards are displayed correctly to a Free user, C1553070', async ({ dashboardPage, page }) => {
await dashboardPage.generateMask(1)
await expect(page.locator(dashboardPage.maskCard)).toHaveScreenshot(`${process.env.E2E_TEST_ENV}-maskCard.png`,
await expect(async () => {
await dashboardPage.generateMask(1)
expect(await page.locator(dashboardPage.maskCard).count() === 1)
}).toPass()
await expect(page.locator(dashboardPage.maskCard)).toHaveScreenshot(`${process.env.E2E_TEST_ENV}-maskCard.png`,
{...defaultScreenshotOpts, mask: [
dashboardPage.maskCardForwardEmail,
dashboardPage.maskCardGeneratedEmail,
dashboardPage.maskCardForwardEmail,
dashboardPage.maskCardGeneratedEmail,
dashboardPage.maskCardCreatedDate
]});
})
test('Check that the user can delete an mask, and is prompted to confirm before they delete, C1553071', async ({ dashboardPage }) => {
await dashboardPage.generateMask(1)
await dashboardPage.maskCardDeleteButton.click()
test.fixme('Check that the user can delete an mask, and is prompted to confirm before they delete, C1553071', async ({ dashboardPage, page }) => {
await expect(async () => {
await dashboardPage.generateMask(1)
expect(await page.locator(dashboardPage.maskCard).count() === 1)
await dashboardPage.maskCardDeleteButton.click()
}).toPass()
await expect(dashboardPage.maskCardDeleteDialogModal).toHaveScreenshot(`${process.env.E2E_TEST_ENV}-maskCardDeleteDialogModal.png`,
{...defaultScreenshotOpts, mask: [
dashboardPage.maskCardDeleteDialogModalEmailString,
dashboardPage.maskCardDeleteDialogModalEmailString,
dashboardPage.maskCardDeleteDialogModalGeneratedEmail
]});
await dashboardPage.maskCardCancelButton.click()
})
})

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 38 KiB

После

Ширина:  |  Высота:  |  Размер: 53 KiB

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 37 KiB