-
Notifications
You must be signed in to change notification settings - Fork 145
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
@W-17682173 Fixing E2E tests failures #2224
Changes from all commits
5cd650c
b3e5120
3b0726c
db48274
ae34972
096e2e2
381add6
e810f58
a56d811
4f7b9d8
b2804e5
6197030
4ccfbc9
65b70db
83c1a5d
eea60fa
736303f
359d1d3
953d25f
c006b9e
1ed1d2a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,91 @@ | ||
/* | ||
* Copyright (c) 2023, Salesforce, Inc. | ||
* All rights reserved. | ||
* SPDX-License-Identifier: BSD-3-Clause | ||
* For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/BSD-3-Clause | ||
*/ | ||
|
||
const { test, expect } = require("@playwright/test"); | ||
const config = require("../../config.js"); | ||
const { | ||
generateUserCredentials | ||
} = require("../../scripts/utils.js"); | ||
const { | ||
registerShopper | ||
} = require("../../scripts/pageHelpers.js") | ||
|
||
const REGISTERED_USER_CREDENTIALS = generateUserCredentials(); | ||
|
||
const checkDntCookie = async (page, expectedValue) => { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thanks for adding more test cases to assert DNT flows. 🥳 |
||
var cookies = await page.context().cookies(); | ||
var cookieName = 'dw_dnt'; | ||
var cookie = cookies.find(cookie => cookie.name === cookieName); | ||
expect(cookie).toBeTruthy(); | ||
expect(cookie.value).toBe(expectedValue); | ||
} | ||
|
||
test("Shopper can use the consent tracking form", async ({ page }) => { | ||
await page.context().clearCookies(); | ||
|
||
await page.goto(config.RETAIL_APP_HOME); | ||
|
||
const modalSelector = '[aria-label="Close consent tracking form"]' | ||
page.locator(modalSelector).waitFor() | ||
await expect(page.getByText(/Tracking Consent/i)).toBeVisible({timeout: 10000}); | ||
|
||
// Decline Tracking | ||
const declineButton = page.locator('button:visible', { hasText: 'Decline' }); | ||
await expect(declineButton).toBeVisible(); | ||
await declineButton.click(); | ||
|
||
// Intercept einstein request | ||
let apiCallsMade = false; | ||
await page.route('https://api.cquotient.com/v3/activities/aaij-MobileFirst/viewCategory', (route) => { | ||
apiCallsMade = true; | ||
route.continue(); | ||
}); | ||
|
||
await checkDntCookie(page, '1') | ||
|
||
// Trigger einstein events | ||
await page.getByLabel("Menu", { exact: true }).click(); | ||
|
||
// SSR nav loads top level categories as direct links so we wait till all sub-categories load in the accordion | ||
const categoryAccordion = page.locator( | ||
"#category-nav .chakra-accordion__button svg+:text('Womens')" | ||
); | ||
await categoryAccordion.waitFor(); | ||
|
||
await page.getByRole("button", { name: "Womens" }).click(); | ||
|
||
const clothingNav = page.getByRole("button", { name: "Clothing" }); | ||
|
||
await clothingNav.waitFor(); | ||
|
||
await clothingNav.click(); | ||
// Reloading the page after setting DNT makes the form not appear again | ||
await page.reload() | ||
await expect(page.getByText(/Tracking Consent/i)).toBeHidden(); | ||
|
||
// Registering after setting DNT persists the preference | ||
await registerShopper({page, userCredentials: REGISTERED_USER_CREDENTIALS}); | ||
await checkDntCookie(page, '1') | ||
|
||
// Logging out clears the preference | ||
await page.getByRole("heading", { name: /My Account/i }).click() | ||
const buttons = await page.getByText(/Log Out/i).elementHandles(); | ||
for (const button of buttons) { | ||
if (await button.isVisible()) { | ||
await button.click(); | ||
break; | ||
} | ||
} | ||
|
||
var cookies = await page.context().cookies(); | ||
if (cookies.some(item => item.name === "dw_dnt")) { | ||
throw new Error('dw_dnt still exists in the cookies'); | ||
} | ||
await page.reload(); | ||
await expect(page.getByText(/Tracking Consent/i)).toBeVisible({timeout: 10000}); | ||
expect(apiCallsMade).toBe(false); | ||
}); |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -153,7 +153,7 @@ test("Registered shopper can add item to wishlist", async ({ page }) => { | |
if(!isLoggedIn) { | ||
await registerShopper({ | ||
page, | ||
userCredentials: REGISTERED_USER_CREDENTIALS, | ||
userCredentials: generateUserCredentials(), | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. While each individual test runs in isolation from the other tests, we must be mindful that the tests are running against a real deployed instance and the global variables in the test file like When |
||
isMobile: true | ||
}) | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As a best practice, it is always better to await the network call and assert on the network response rather than waiting for pageLoadState(). If an assert after the await for pageLoadState times out, the lock for pageloadstate will be released while the previous network call is still in progress. This will lead to race conditions where if the network call takes longer than the await timeout, the test flow will incorrectly assume the network called failed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we want this in a comment somewhere so we don't forget to do this in future tests?