From 2ec039a8f1dcfcaae0df1eb4b8462d37a0b1bd7f Mon Sep 17 00:00:00 2001 From: Tijl Leenders Date: Sun, 22 Sep 2024 17:34:41 +0200 Subject: [PATCH 01/27] update playwright --- package-lock.json | 29 +++++++++++++++++------------ package.json | 2 +- src/version.json | 6 +++--- 3 files changed, 21 insertions(+), 16 deletions(-) diff --git a/package-lock.json b/package-lock.json index 8d054ed41..bbc877829 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12,7 +12,6 @@ "@dnd-kit/sortable": "^8.0.0", "@dnd-kit/utilities": "^3.2.2", "@jest/globals": "^28.1.0", - "@playwright/test": "^1.38.1", "@testing-library/jest-dom": "^5.16.1", "@testing-library/react": "^11.2.7", "@types/node": "^17.0.31", @@ -49,6 +48,7 @@ "@babel/preset-env": "^7.18.2", "@babel/preset-react": "^7.17.12", "@babel/preset-typescript": "^7.17.12", + "@playwright/test": "^1.47.2", "@types/crypto-js": "^4.1.1", "@typescript-eslint/eslint-plugin": "^5.22.0", "@typescript-eslint/parser": "^5.22.0", @@ -3374,12 +3374,13 @@ } }, "node_modules/@playwright/test": { - "version": "1.45.1", - "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.45.1.tgz", - "integrity": "sha512-Wo1bWTzQvGA7LyKGIZc8nFSTFf2TkthGIFBR+QVNilvwouGzFd4PYukZe3rvf5PSqjHi1+1NyKSDZKcQWETzaA==", + "version": "1.47.2", + "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.47.2.tgz", + "integrity": "sha512-jTXRsoSPONAs8Za9QEQdyjFn+0ZQFjCiIztAIF6bi1HqhBzG9Ma7g1WotyiGqFSBRZjIEqMdT8RUlbk1QVhzCQ==", + "dev": true, "license": "Apache-2.0", "dependencies": { - "playwright": "1.45.1" + "playwright": "1.47.2" }, "bin": { "playwright": "cli.js" @@ -10871,12 +10872,13 @@ } }, "node_modules/playwright": { - "version": "1.45.1", - "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.45.1.tgz", - "integrity": "sha512-Hjrgae4kpSQBr98nhCj3IScxVeVUixqj+5oyif8TdIn2opTCPEzqAqNMeK42i3cWDCVu9MI+ZsGWw+gVR4ISBg==", + "version": "1.47.2", + "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.47.2.tgz", + "integrity": "sha512-nx1cLMmQWqmA3UsnjaaokyoUpdVaaDhJhMoxX2qj3McpjnsqFHs516QAKYhqHAgOP+oCFTEOCOAaD1RgD/RQfA==", + "dev": true, "license": "Apache-2.0", "dependencies": { - "playwright-core": "1.45.1" + "playwright-core": "1.47.2" }, "bin": { "playwright": "cli.js" @@ -10889,9 +10891,10 @@ } }, "node_modules/playwright-core": { - "version": "1.45.1", - "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.45.1.tgz", - "integrity": "sha512-LF4CUUtrUu2TCpDw4mcrAIuYrEjVDfT1cHbJMfwnE2+1b8PZcFzPNgvZCvq2JfQ4aTjRCCHw5EJ2tmr2NSzdPg==", + "version": "1.47.2", + "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.47.2.tgz", + "integrity": "sha512-3JvMfF+9LJfe16l7AbSmU555PaTl2tPyQsVInqm3id16pdDfvZ8TTZ/pyzmkbDrZTQefyzU7AIHlZqQnxpqHVQ==", + "dev": true, "license": "Apache-2.0", "bin": { "playwright-core": "cli.js" @@ -10904,7 +10907,9 @@ "version": "2.3.2", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "dev": true, "hasInstallScript": true, + "license": "MIT", "optional": true, "os": [ "darwin" diff --git a/package.json b/package.json index 4163aec1e..647a8f278 100644 --- a/package.json +++ b/package.json @@ -12,7 +12,6 @@ "@dnd-kit/sortable": "^8.0.0", "@dnd-kit/utilities": "^3.2.2", "@jest/globals": "^28.1.0", - "@playwright/test": "^1.38.1", "@testing-library/jest-dom": "^5.16.1", "@testing-library/react": "^11.2.7", "@types/node": "^17.0.31", @@ -84,6 +83,7 @@ "@babel/preset-env": "^7.18.2", "@babel/preset-react": "^7.17.12", "@babel/preset-typescript": "^7.17.12", + "@playwright/test": "^1.47.2", "@types/crypto-js": "^4.1.1", "@typescript-eslint/eslint-plugin": "^5.22.0", "@typescript-eslint/parser": "^5.22.0", diff --git a/src/version.json b/src/version.json index 2bf92ee69..045d6e1ae 100644 --- a/src/version.json +++ b/src/version.json @@ -1,7 +1,7 @@ { "buildHash": { - "schedulerFileHash": "409e79b3", - "indexFileHash": "10a6f235" + "schedulerFileHash": "b66a66a2", + "indexFileHash": "94f0e947" }, - "buildDate": "2024-08-14T13:23:54.232Z" + "buildDate": "2024-09-22T10:46:12.194Z" } From 2c1cdd891f2cb75722f825cdf2f076afeb8bfc7c Mon Sep 17 00:00:00 2001 From: Tijl Leenders Date: Sun, 22 Sep 2024 17:34:59 +0200 Subject: [PATCH 02/27] fix local server port --- playwright.config.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/playwright.config.ts b/playwright.config.ts index 4b3137558..33e4d1b68 100644 --- a/playwright.config.ts +++ b/playwright.config.ts @@ -71,7 +71,7 @@ export default defineConfig({ /* Run your local dev server before starting the tests */ webServer: { command: "npm run dev", - url: "http://127.0.0.1:3000", + url: "http://127.0.0.1:5173", reuseExistingServer: !process.env.CI, }, }); From dff4f572c0251c4e724f9a9d06b269f85c783eec Mon Sep 17 00:00:00 2001 From: Tijl Leenders Date: Sun, 22 Sep 2024 17:35:33 +0200 Subject: [PATCH 03/27] github action to run latest playwright --- .github/workflows/playwright.yml | 36 ++++++++++++++++---------------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/.github/workflows/playwright.yml b/.github/workflows/playwright.yml index 181221158..3eb13143c 100644 --- a/.github/workflows/playwright.yml +++ b/.github/workflows/playwright.yml @@ -1,27 +1,27 @@ name: Playwright Tests on: push: - branches: [main, master] + branches: [ main, master ] pull_request: - branches: [main, master] + branches: [ main, master ] jobs: test: timeout-minutes: 60 runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 - - uses: actions/setup-node@v4 - with: - node-version: 18 - - name: Install dependencies - run: npm ci - - name: Install Playwright Browsers - run: npx playwright install --with-deps - - name: Run Playwright tests - run: npx playwright test - - uses: actions/upload-artifact@v4 - if: always() - with: - name: playwright-report - path: playwright-report/ - retention-days: 30 + - uses: actions/checkout@v4 + - uses: actions/setup-node@v4 + with: + node-version: lts/* + - name: Install dependencies + run: npm ci + - name: Install Playwright Browsers + run: npx playwright install --with-deps + - name: Run Playwright tests + run: npx playwright test + - uses: actions/upload-artifact@v4 + if: ${{ !cancelled() }} + with: + name: playwright-report + path: playwright-report/ + retention-days: 30 From 44d63efe61cd6813b097c78d3cd754c0d517c68d Mon Sep 17 00:00:00 2001 From: Tijl Leenders Date: Sun, 22 Sep 2024 17:49:20 +0200 Subject: [PATCH 04/27] set port to 3000 --- playwright.config.ts | 2 +- vite.config.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/playwright.config.ts b/playwright.config.ts index 33e4d1b68..4b3137558 100644 --- a/playwright.config.ts +++ b/playwright.config.ts @@ -71,7 +71,7 @@ export default defineConfig({ /* Run your local dev server before starting the tests */ webServer: { command: "npm run dev", - url: "http://127.0.0.1:5173", + url: "http://127.0.0.1:3000", reuseExistingServer: !process.env.CI, }, }); diff --git a/vite.config.ts b/vite.config.ts index a509fc523..7a0b86b10 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -24,7 +24,7 @@ export default defineConfig({ }, server: { host: "127.0.0.1", - port: 5173, + port: 3000, }, plugins: [ VitePWA({ From d4538b9b65ca6d23f9de2c76d442fdf3d28ff9d5 Mon Sep 17 00:00:00 2001 From: Vinay Badgujar Date: Fri, 4 Oct 2024 12:19:34 +0530 Subject: [PATCH 05/27] update: config goal ui playwright test --- playwright/tests/config-goal-ui.spec.ts | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/playwright/tests/config-goal-ui.spec.ts b/playwright/tests/config-goal-ui.spec.ts index 8a8d18257..4265c70de 100644 --- a/playwright/tests/config-goal-ui.spec.ts +++ b/playwright/tests/config-goal-ui.spec.ts @@ -10,8 +10,7 @@ test.describe("Config Goal UI", () => { test("should add a new goal after pressing Enter key", async ({ page }) => { await page.getByRole("button", { name: "Goals" }).click(); - await page.getByRole("button", { name: "add goal | add feeling | add group", exact: true }).click(); - await page.getByRole("button", { name: "Goal add goal", exact: true }).click(); + await page.getByRole("button", { name: "add goal | add feeling | add group", exact: true }).click({}); const titleInputContainer = page.getByPlaceholder("Goal title"); const testGoalTitle = "Test Goal"; @@ -24,7 +23,9 @@ test.describe("Config Goal UI", () => { test("should add a new budget after pressing Enter key", async ({ page }) => { await page.getByRole("button", { name: "Goals" }).click(); - await page.getByRole("button", { name: "add goal | add feeling | add group", exact: true }).click(); + await page.getByRole("button", { name: "add goal | add feeling | add group", exact: true }).click({ + delay: 1000, + }); await page.getByRole("button", { name: "Budget add goal", exact: true }).click(); const titleInputContainer = page.getByPlaceholder("Budget title"); From a6a8dc44a0dc4e9240e58bd52468fd361e98ce41 Mon Sep 17 00:00:00 2001 From: Vinay Badgujar Date: Fri, 4 Oct 2024 13:53:23 +0530 Subject: [PATCH 06/27] fix: collaboration playwright test --- .../goal-collaboration-feature.spec.ts | 19 +++++++++++++------ .../utils/collaboration-feature-utils.ts | 6 ++---- .../MyGoalActions/RegularGoalActions.tsx | 1 + 3 files changed, 16 insertions(+), 10 deletions(-) diff --git a/playwright/tests/collaboration-feature/goal-collaboration-feature.spec.ts b/playwright/tests/collaboration-feature/goal-collaboration-feature.spec.ts index e0f4a335d..f87fad817 100644 --- a/playwright/tests/collaboration-feature/goal-collaboration-feature.spec.ts +++ b/playwright/tests/collaboration-feature/goal-collaboration-feature.spec.ts @@ -15,9 +15,6 @@ import { test.describe.configure({ mode: "serial" }); test.describe("Goal Sharing Feature", () => { - let userAContext; - let userBContext; - let userCContext; let userAPage: Page; let userBPage: Page; let userCPage: Page; @@ -25,9 +22,18 @@ test.describe("Goal Sharing Feature", () => { let currentGoalTitle: string; test.beforeAll(async ({ browser }) => { - ({ context: userAContext, page: userAPage } = await createUserContextAndPage(browser, STORAGE_STATE)); - ({ context: userBContext, page: userBPage } = await createUserContextAndPage(browser, STORAGE_STATE)); - ({ context: userCContext, page: userCPage } = await createUserContextAndPage(browser, STORAGE_STATE)); + ({ page: userAPage } = await createUserContextAndPage(browser)); + ({ page: userBPage } = await createUserContextAndPage(browser)); + ({ page: userCPage } = await createUserContextAndPage(browser)); + await userAPage.goto("http://127.0.0.1:3000/"); + await userAPage.getByText("English").click(); + await userAPage.getByRole("button", { name: "Continue zinzen faq" }).click(); + await userBPage.goto("http://127.0.0.1:3000/"); + await userBPage.getByText("English").click(); + await userBPage.getByRole("button", { name: "Continue zinzen faq" }).click(); + await userCPage.goto("http://127.0.0.1:3000/"); + await userCPage.getByText("English").click(); + await userCPage.getByRole("button", { name: "Continue zinzen faq" }).click(); }); const userCollaborationScenarios = [ @@ -94,6 +100,7 @@ test.describe("Goal Sharing Feature", () => { }); test(`check if collaborated goal is visible in User ${receiver}'s MyGoal`, async () => { + await receiverPage().goto("http://127.0.0.1:3000/"); await receiverPage().getByRole("button", { name: "Goals" }).click(); await expect(receiverPage().locator(".goal-title").first().locator("span")).toContainText(currentGoalTitle); }); diff --git a/playwright/utils/collaboration-feature-utils.ts b/playwright/utils/collaboration-feature-utils.ts index fb4440fc6..e37d1027a 100644 --- a/playwright/utils/collaboration-feature-utils.ts +++ b/playwright/utils/collaboration-feature-utils.ts @@ -1,9 +1,7 @@ import { Browser, Page, expect } from "@playwright/test"; -export async function createUserContextAndPage(browser: Browser, storageState: string) { - const context = await browser.newContext({ - storageState, - }); +export async function createUserContextAndPage(browser: Browser) { + const context = await browser.newContext(); const page = await context.newPage(); return { context, page }; } diff --git a/src/components/GoalsComponents/MyGoalActions/RegularGoalActions.tsx b/src/components/GoalsComponents/MyGoalActions/RegularGoalActions.tsx index 28d006f16..fed2f1dec 100644 --- a/src/components/GoalsComponents/MyGoalActions/RegularGoalActions.tsx +++ b/src/components/GoalsComponents/MyGoalActions/RegularGoalActions.tsx @@ -62,6 +62,7 @@ const RegularGoalActions = ({ goal }: { goal: GoalItem }) => { await handleArchiveGoal(goal, ancestors); } else if (action === "colabRequest") { await convertSharedWMGoalToColab(goal); + setLastAction("goalColabRequest"); } window.history.back(); }; From 254c002221c41f4e27455b53850f2da00fe3b557 Mon Sep 17 00:00:00 2001 From: Vinay Badgujar Date: Fri, 4 Oct 2024 14:02:23 +0530 Subject: [PATCH 07/27] fix: other playwright tests --- .../tests/bottom-nav/navigation.spec.ts | 4 +- .../goal-sharing-feature.spec.ts | 58 ------------------- playwright/tests/header-ui.spec.ts | 5 +- playwright/tests/landing-page.spec.ts | 2 +- 4 files changed, 5 insertions(+), 64 deletions(-) delete mode 100644 playwright/tests/collaboration-feature/goal-sharing-feature.spec.ts diff --git a/playwright/tests/bottom-nav/navigation.spec.ts b/playwright/tests/bottom-nav/navigation.spec.ts index 388e0e38f..d49317783 100644 --- a/playwright/tests/bottom-nav/navigation.spec.ts +++ b/playwright/tests/bottom-nav/navigation.spec.ts @@ -2,10 +2,10 @@ import { test, expect } from "@playwright/test"; import { STORAGE_STATE } from "playwright/config/constants"; test.describe("BottomNavbar", () => { - test.use({ storageState: STORAGE_STATE }); - test.beforeEach(async ({ page }) => { await page.goto("http://127.0.0.1:3000/"); + await page.getByText("English").click(); + await page.getByRole("button", { name: "Continue zinzen faq" }).click(); }); test("should navigate to MyTime when Schedule button is clicked", async ({ page }) => { diff --git a/playwright/tests/collaboration-feature/goal-sharing-feature.spec.ts b/playwright/tests/collaboration-feature/goal-sharing-feature.spec.ts deleted file mode 100644 index 10cb4cf78..000000000 --- a/playwright/tests/collaboration-feature/goal-sharing-feature.spec.ts +++ /dev/null @@ -1,58 +0,0 @@ -import { test, expect, Page } from "@playwright/test"; -import { API_SERVER_URL, API_SERVER_URL_GOAL } from "playwright/config/constants"; -import { - acceptContactInvitation, - addContact, - goToMyGoalsPageFlow, - goToShareGoalModalFlow, - waitForResponseConfirmation, -} from "playwright/utils/collaboration-feature-utils"; - -test.describe.configure({ mode: "serial" }); - -test.describe("Goal Sharing Feature", () => { - let userOneContext; - let userTwoContext; - let userOnePage: Page; - let userTwoPage: Page; - let invitationLink: string; - let currentGoalTitle: string; - - test.beforeAll(async ({ browser }) => { - userOneContext = await browser.newContext({ - storageState: "playwright/userOnboarding.json", - }); - userTwoContext = await browser.newContext({ - storageState: "playwright/userOnboarding.json", - }); - - userOnePage = await userOneContext.newPage(); - userTwoPage = await userTwoContext.newPage(); - }); - - test("from User One share invitation to User Two", async () => { - await goToMyGoalsPageFlow(userOnePage); - currentGoalTitle = await userOnePage.locator(".goal-title").first().locator("span").innerText(); - invitationLink = await addContact(userOnePage, "User Two", "relId", "relationshipId"); - await goToMyGoalsPageFlow(userOnePage); - await goToShareGoalModalFlow(userOnePage); - }); - - test("from User Two accept invitation of User One", async () => { - await acceptContactInvitation(userTwoPage, invitationLink, "User Two"); - await waitForResponseConfirmation(userTwoPage, API_SERVER_URL, "accepted"); - }); - - test("share goal from User One to User Two", async () => { - await userOnePage.getByRole("button", { name: "U", exact: true }).click(); - await userOnePage.waitForSelector(".ant-notification-notice"); - }); - - test("check whether shared goal is visible in User Two's patner goal", async () => { - await userTwoPage.reload(); - await waitForResponseConfirmation(userTwoPage, API_SERVER_URL_GOAL, "shareMessage"); - await userTwoPage.getByRole("img", { name: "ZinZen" }).click(); - await userTwoPage.reload(); - await expect(userTwoPage.locator(".user-goal-main")).toBeVisible(); - }); -}); diff --git a/playwright/tests/header-ui.spec.ts b/playwright/tests/header-ui.spec.ts index fa1d288bc..69f9cbf2b 100644 --- a/playwright/tests/header-ui.spec.ts +++ b/playwright/tests/header-ui.spec.ts @@ -1,11 +1,10 @@ import { test, expect } from "@playwright/test"; -import { STORAGE_STATE } from "playwright/config/constants"; test.describe("Header component", () => { - test.use({ storageState: STORAGE_STATE }); - test.beforeEach(async ({ page }) => { await page.goto("http://127.0.0.1:3000/"); + await page.getByText("English").click(); + await page.getByRole("button", { name: "Continue zinzen faq" }).click(); }); test("should display the title correctly", async ({ page }) => { diff --git a/playwright/tests/landing-page.spec.ts b/playwright/tests/landing-page.spec.ts index 841569148..1d23ade72 100644 --- a/playwright/tests/landing-page.spec.ts +++ b/playwright/tests/landing-page.spec.ts @@ -10,7 +10,7 @@ test.describe("Onboarding", () => { test("should select a language and navigate to the FAQ page", async () => { await page.goto("http://127.0.0.1:3000/"); - await page.getByRole("button", { name: "English" }).click(); + await page.getByText("English").click(); await expect(page).toHaveURL("http://127.0.0.1:3000/ZinZenFAQ"); }); From 7e462af0b9f13e1c95b38f837e008dc084684e2e Mon Sep 17 00:00:00 2001 From: Vinay Badgujar Date: Fri, 4 Oct 2024 14:26:16 +0530 Subject: [PATCH 08/27] add: retires to collaboration playwright test for response confirmation --- .../utils/collaboration-feature-utils.ts | 80 +++++++++++++++---- 1 file changed, 65 insertions(+), 15 deletions(-) diff --git a/playwright/utils/collaboration-feature-utils.ts b/playwright/utils/collaboration-feature-utils.ts index e37d1027a..c35b88958 100644 --- a/playwright/utils/collaboration-feature-utils.ts +++ b/playwright/utils/collaboration-feature-utils.ts @@ -23,15 +23,42 @@ export async function waitForResponseConfirmation( page: Page, urlContains: string, responseBodyIncludes: string, + maxRetries: number = 3, + retryDelay: number = 15000, ): Promise { - await page.waitForResponse( - async (response) => - response.status() === 200 && - response.url().includes(urlContains) && - (await response.text()).includes(responseBodyIncludes), - ); -} + for (let attempt = 1; attempt <= maxRetries; attempt++) { + try { + const response = await page.waitForResponse( + async (response) => { + const status = response.status(); + const url = response.url(); + const text = await response.text(); + const isMatch = status === 200 && url.includes(urlContains) && text.includes(responseBodyIncludes); + + console.log(`Attempt ${attempt} - Response details: + Status: ${status} + URL: ${url} + Includes expected body: ${text.includes(responseBodyIncludes)} + Is match: ${isMatch}`); + return isMatch; + }, + { timeout: 10000 }, + ); + + console.log(`Success on attempt ${attempt}`); + console.log(`Response: ${JSON.stringify(response)}`); + return; + } catch (error) { + if (attempt === maxRetries) { + console.error(`All ${maxRetries} attempts failed. Last error: ${error.message}`); + throw new Error(`Failed to get response confirmation after ${maxRetries} attempts: ${error.message}`); + } + console.warn(`Attempt ${attempt} failed. Retrying in ${retryDelay}ms...`); + await page.waitForTimeout(retryDelay); + } + } +} export async function addContact( page: Page, contactName: string, @@ -71,13 +98,36 @@ export async function goToMyGoalsPageFlow(page: Page) { await page.getByRole("button", { name: "Goals" }).click(); } -export async function verifyUpdatedGoal(page: Page, expectedGoalTitle: string, apiUrlGoal: string): Promise { - await page.goto("http://127.0.0.1:3000/"); - await Promise.all([page.waitForResponse((res) => res.status() === 200 && res.url().includes(apiUrlGoal))]); +export async function verifyUpdatedGoal( + page: Page, + expectedGoalTitle: string, + apiUrlGoal: string, + maxRetries: number = 3, + retryDelay: number = 2000, +): Promise { + for (let attempt = 1; attempt <= maxRetries; attempt++) { + try { + await page.goto("http://127.0.0.1:3000/"); + await Promise.all([ + page.waitForResponse((res) => res.status() === 200 && res.url().includes(apiUrlGoal), { timeout: 10000 }), + ]); - await page.getByRole("button", { name: "Goals" }).click(); - await page.locator(".goal-dd-outer").first().click(); - await expect(page.getByText(expectedGoalTitle).first()).toBeVisible(); - await page.getByRole("button", { name: "add changes Make all checked" }).click(); - await expect(page.getByText(expectedGoalTitle).first()).toBeVisible(); + await page.getByRole("button", { name: "Goals" }).click(); + await page.locator(".goal-dd-outer").first().click(); + + await page.waitForSelector(`text=${expectedGoalTitle}`, { timeout: 10000 }); + + await page.getByRole("button", { name: "add changes Make all checked" }).click(); + + await page.waitForSelector(`text=${expectedGoalTitle}`, { timeout: 10000 }); + + return; + } catch (error) { + if (attempt === maxRetries) { + throw new Error(`Failed to verify updated goal after ${maxRetries} attempts: ${error.message}`); + } + console.warn(`Attempt ${attempt} failed. Retrying in ${retryDelay}ms...`); + await page.waitForTimeout(retryDelay); + } + } } From deabe69d59366ce7b07e034f8777d938651ab8d3 Mon Sep 17 00:00:00 2001 From: Vinay Badgujar Date: Fri, 4 Oct 2024 14:49:29 +0530 Subject: [PATCH 09/27] edit: increase collaboration timeout limit --- .../collaboration-feature/goal-collaboration-feature.spec.ts | 2 +- playwright/utils/collaboration-feature-utils.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/playwright/tests/collaboration-feature/goal-collaboration-feature.spec.ts b/playwright/tests/collaboration-feature/goal-collaboration-feature.spec.ts index f87fad817..ca8854eb4 100644 --- a/playwright/tests/collaboration-feature/goal-collaboration-feature.spec.ts +++ b/playwright/tests/collaboration-feature/goal-collaboration-feature.spec.ts @@ -12,7 +12,7 @@ import { waitForResponseConfirmation, } from "../../utils/collaboration-feature-utils"; -test.describe.configure({ mode: "serial" }); +test.describe.configure({ mode: "serial", timeout: 100000 }); test.describe("Goal Sharing Feature", () => { let userAPage: Page; diff --git a/playwright/utils/collaboration-feature-utils.ts b/playwright/utils/collaboration-feature-utils.ts index c35b88958..1f6f2345d 100644 --- a/playwright/utils/collaboration-feature-utils.ts +++ b/playwright/utils/collaboration-feature-utils.ts @@ -24,7 +24,7 @@ export async function waitForResponseConfirmation( urlContains: string, responseBodyIncludes: string, maxRetries: number = 3, - retryDelay: number = 15000, + retryDelay: number = 2000, ): Promise { for (let attempt = 1; attempt <= maxRetries; attempt++) { try { From 8e368ad9fb95e3dd993830fcf88ae1fe73103ea5 Mon Sep 17 00:00:00 2001 From: Vinay Badgujar Date: Fri, 4 Oct 2024 18:27:51 +0530 Subject: [PATCH 10/27] add: run playwright in headful mode in ci/cd --- .github/workflows/playwright.yml | 36 +++++++++---------- .../goal-collaboration-feature.spec.ts | 2 +- .../utils/collaboration-feature-utils.ts | 4 +-- 3 files changed, 21 insertions(+), 21 deletions(-) diff --git a/.github/workflows/playwright.yml b/.github/workflows/playwright.yml index 3eb13143c..7b991f5e8 100644 --- a/.github/workflows/playwright.yml +++ b/.github/workflows/playwright.yml @@ -1,27 +1,27 @@ name: Playwright Tests on: push: - branches: [ main, master ] + branches: [main, master] pull_request: - branches: [ main, master ] + branches: [main, master] jobs: test: timeout-minutes: 60 runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 - - uses: actions/setup-node@v4 - with: - node-version: lts/* - - name: Install dependencies - run: npm ci - - name: Install Playwright Browsers - run: npx playwright install --with-deps - - name: Run Playwright tests - run: npx playwright test - - uses: actions/upload-artifact@v4 - if: ${{ !cancelled() }} - with: - name: playwright-report - path: playwright-report/ - retention-days: 30 + - uses: actions/checkout@v4 + - uses: actions/setup-node@v4 + with: + node-version: lts/* + - name: Install dependencies + run: npm ci + - name: Install Playwright Browsers + run: npx playwright install --with-deps + - name: Run Playwright tests + run: xvfb-run npx playwright test + - uses: actions/upload-artifact@v4 + if: ${{ !cancelled() }} + with: + name: playwright-report + path: playwright-report/ + retention-days: 30 diff --git a/playwright/tests/collaboration-feature/goal-collaboration-feature.spec.ts b/playwright/tests/collaboration-feature/goal-collaboration-feature.spec.ts index ca8854eb4..a8d317a7b 100644 --- a/playwright/tests/collaboration-feature/goal-collaboration-feature.spec.ts +++ b/playwright/tests/collaboration-feature/goal-collaboration-feature.spec.ts @@ -1,5 +1,5 @@ import { test, expect, Page } from "@playwright/test"; -import { API_SERVER_URL, API_SERVER_URL_GOAL, STORAGE_STATE } from "playwright/config/constants"; +import { API_SERVER_URL, API_SERVER_URL_GOAL } from "playwright/config/constants"; import { acceptContactInvitation, addContact, diff --git a/playwright/utils/collaboration-feature-utils.ts b/playwright/utils/collaboration-feature-utils.ts index 1f6f2345d..469a07b8c 100644 --- a/playwright/utils/collaboration-feature-utils.ts +++ b/playwright/utils/collaboration-feature-utils.ts @@ -24,7 +24,7 @@ export async function waitForResponseConfirmation( urlContains: string, responseBodyIncludes: string, maxRetries: number = 3, - retryDelay: number = 2000, + retryDelay: number = 3000, ): Promise { for (let attempt = 1; attempt <= maxRetries; attempt++) { try { @@ -43,7 +43,7 @@ export async function waitForResponseConfirmation( return isMatch; }, - { timeout: 10000 }, + { timeout: 30000 }, ); console.log(`Success on attempt ${attempt}`); From 7f11bc6aaeee7296e24c0bf69c839aad702c0017 Mon Sep 17 00:00:00 2001 From: Vinay Badgujar Date: Fri, 4 Oct 2024 19:22:10 +0530 Subject: [PATCH 11/27] edit: increase retries for collaboration playwright test --- .github/workflows/playwright.yml | 2 +- playwright.config.ts | 2 +- playwright/utils/collaboration-feature-utils.ts | 1 + 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/playwright.yml b/.github/workflows/playwright.yml index 7b991f5e8..884700bb1 100644 --- a/.github/workflows/playwright.yml +++ b/.github/workflows/playwright.yml @@ -18,7 +18,7 @@ jobs: - name: Install Playwright Browsers run: npx playwright install --with-deps - name: Run Playwright tests - run: xvfb-run npx playwright test + run: xvfb-run npx playwright test --headed - uses: actions/upload-artifact@v4 if: ${{ !cancelled() }} with: diff --git a/playwright.config.ts b/playwright.config.ts index 4b3137558..addd0293e 100644 --- a/playwright.config.ts +++ b/playwright.config.ts @@ -16,7 +16,7 @@ export default defineConfig({ /* Fail the build on CI if you accidentally left test.only in the source code. */ forbidOnly: !!process.env.CI, /* Retry on CI only */ - retries: process.env.CI ? 2 : 0, + retries: process.env.CI ? 3 : 0, /* Opt out of parallel tests on CI. */ workers: process.env.CI ? 1 : undefined, /* Reporter to use. See https://playwright.dev/docs/test-reporters */ diff --git a/playwright/utils/collaboration-feature-utils.ts b/playwright/utils/collaboration-feature-utils.ts index 469a07b8c..ae727292c 100644 --- a/playwright/utils/collaboration-feature-utils.ts +++ b/playwright/utils/collaboration-feature-utils.ts @@ -34,6 +34,7 @@ export async function waitForResponseConfirmation( const url = response.url(); const text = await response.text(); const isMatch = status === 200 && url.includes(urlContains) && text.includes(responseBodyIncludes); + console.log(text); console.log(`Attempt ${attempt} - Response details: Status: ${status} From e18f2863663c581b5ca3e99b05fe2d8d63a28941 Mon Sep 17 00:00:00 2001 From: Vinay Badgujar Date: Sat, 5 Oct 2024 14:17:07 +0530 Subject: [PATCH 12/27] fix: add appropriate reloads --- playwright.config.ts | 2 +- .../goal-collaboration-feature.spec.ts | 4 +-- .../utils/collaboration-feature-utils.ts | 27 +++++-------------- 3 files changed, 9 insertions(+), 24 deletions(-) diff --git a/playwright.config.ts b/playwright.config.ts index addd0293e..f8e6d32d9 100644 --- a/playwright.config.ts +++ b/playwright.config.ts @@ -16,7 +16,7 @@ export default defineConfig({ /* Fail the build on CI if you accidentally left test.only in the source code. */ forbidOnly: !!process.env.CI, /* Retry on CI only */ - retries: process.env.CI ? 3 : 0, + retries: process.env.CI ? 5 : 0, /* Opt out of parallel tests on CI. */ workers: process.env.CI ? 1 : undefined, /* Reporter to use. See https://playwright.dev/docs/test-reporters */ diff --git a/playwright/tests/collaboration-feature/goal-collaboration-feature.spec.ts b/playwright/tests/collaboration-feature/goal-collaboration-feature.spec.ts index a8d317a7b..f0371885e 100644 --- a/playwright/tests/collaboration-feature/goal-collaboration-feature.spec.ts +++ b/playwright/tests/collaboration-feature/goal-collaboration-feature.spec.ts @@ -79,7 +79,7 @@ test.describe("Goal Sharing Feature", () => { test(`from User ${receiver} accept invitation of User ${sharer}`, async () => { await acceptContactInvitation(receiverPage(), invitationLink, receiver); - await waitForResponseConfirmation(receiverPage(), API_SERVER_URL, "accepted"); + await waitForResponseConfirmation(receiverPage(), API_SERVER_URL); }); test(`share goal from User ${receiver} to User ${sharer}`, async () => { @@ -89,7 +89,7 @@ test.describe("Goal Sharing Feature", () => { test(`check whether shared goal is visible in User ${receiver}'s patner goal`, async () => { await receiverPage().reload(); - await waitForResponseConfirmation(receiverPage(), API_SERVER_URL_GOAL, "shareMessage"); + await waitForResponseConfirmation(receiverPage(), API_SERVER_URL_GOAL); await receiverPage().getByRole("img", { name: "ZinZen" }).click(); await receiverPage().reload(); await expect(receiverPage().locator(".user-goal-main")).toBeVisible(); diff --git a/playwright/utils/collaboration-feature-utils.ts b/playwright/utils/collaboration-feature-utils.ts index ae727292c..2fbcce310 100644 --- a/playwright/utils/collaboration-feature-utils.ts +++ b/playwright/utils/collaboration-feature-utils.ts @@ -22,30 +22,15 @@ export async function goToShareGoalModalFlow(page: Page) { export async function waitForResponseConfirmation( page: Page, urlContains: string, - responseBodyIncludes: string, maxRetries: number = 3, retryDelay: number = 3000, ): Promise { for (let attempt = 1; attempt <= maxRetries; attempt++) { try { - const response = await page.waitForResponse( - async (response) => { - const status = response.status(); - const url = response.url(); - const text = await response.text(); - const isMatch = status === 200 && url.includes(urlContains) && text.includes(responseBodyIncludes); - console.log(text); - - console.log(`Attempt ${attempt} - Response details: - Status: ${status} - URL: ${url} - Includes expected body: ${text.includes(responseBodyIncludes)} - Is match: ${isMatch}`); - - return isMatch; - }, - { timeout: 30000 }, - ); + if (attempt > 1) { + await page.reload(); + } + const response = await page.waitForResponse((res) => res.url().includes(urlContains) && res.status() === 200); console.log(`Success on attempt ${attempt}`); console.log(`Response: ${JSON.stringify(response)}`); @@ -74,10 +59,10 @@ export async function addContact( await page.getByPlaceholder("Name").click(); await page.getByPlaceholder("Name").fill(contactName); await page.getByRole("button", { name: "add contact Share invitation" }).click(); - await waitForResponseConfirmation(page, apiServerUrl, expectedApiResponse1); + await waitForResponseConfirmation(page, apiServerUrl); await page.goBack(); await page.getByRole("button", { name: contactName.slice(0, 1), exact: true }).click(); - await waitForResponseConfirmation(page, apiServerUrl, expectedApiResponse2); + await waitForResponseConfirmation(page, apiServerUrl); await page.waitForSelector(".ant-notification-notice"); return page.evaluate("navigator.clipboard.readText()"); } From c358394503d877df9e04d6ca230b8abb16f418e0 Mon Sep 17 00:00:00 2001 From: Vinay Badgujar Date: Sat, 5 Oct 2024 15:22:30 +0530 Subject: [PATCH 13/27] edit: create new goal and share that goal in test --- .../goal-collaboration-feature.spec.ts | 24 ++++++--- .../utils/collaboration-feature-utils.ts | 53 +++++++++++++------ 2 files changed, 55 insertions(+), 22 deletions(-) diff --git a/playwright/tests/collaboration-feature/goal-collaboration-feature.spec.ts b/playwright/tests/collaboration-feature/goal-collaboration-feature.spec.ts index f0371885e..d8a44d4d5 100644 --- a/playwright/tests/collaboration-feature/goal-collaboration-feature.spec.ts +++ b/playwright/tests/collaboration-feature/goal-collaboration-feature.spec.ts @@ -19,7 +19,7 @@ test.describe("Goal Sharing Feature", () => { let userBPage: Page; let userCPage: Page; let invitationLink: string; - let currentGoalTitle: string; + let currentGoalTitle = "Test Goal"; test.beforeAll(async ({ browser }) => { ({ page: userAPage } = await createUserContextAndPage(browser)); @@ -36,6 +36,12 @@ test.describe("Goal Sharing Feature", () => { await userCPage.getByRole("button", { name: "Continue zinzen faq" }).click(); }); + test.afterAll(async () => { + await userAPage.close(); + await userBPage.close(); + await userCPage.close(); + }); + const userCollaborationScenarios = [ { sharer: "A", receiver: "B", sharerPage: () => userAPage, receiverPage: () => userBPage }, { sharer: "B", receiver: "C", sharerPage: () => userBPage, receiverPage: () => userCPage }, @@ -71,10 +77,16 @@ test.describe("Goal Sharing Feature", () => { userCollaborationScenarios.forEach(({ sharer, receiver, sharerPage, receiverPage }) => { test(`from User ${sharer} share invitation to User ${receiver}`, async () => { await goToMyGoalsPageFlow(sharerPage()); - currentGoalTitle = await sharerPage().locator(".goal-title").first().locator("span").innerText(); - invitationLink = await addContact(sharerPage(), receiver, "relId", "relationshipId"); + if (sharer === "A") { + await sharerPage().getByRole("button", { name: "add goal | add feeling | add group", exact: true }).click({}); + + const titleInputContainer = sharerPage().getByPlaceholder("Goal title"); + await titleInputContainer.fill(currentGoalTitle); + await titleInputContainer.press("Enter"); + } + invitationLink = await addContact(sharerPage(), receiver, currentGoalTitle, "relId", "relationshipId"); await goToMyGoalsPageFlow(sharerPage()); - await goToShareGoalModalFlow(sharerPage()); + await goToShareGoalModalFlow(sharerPage(), currentGoalTitle); }); test(`from User ${receiver} accept invitation of User ${sharer}`, async () => { @@ -96,7 +108,7 @@ test.describe("Goal Sharing Feature", () => { }); test(`initiate collaboration between User ${sharer} and User ${receiver}`, async () => { - await collaborateFlow(receiverPage()); + await collaborateFlow(receiverPage(), currentGoalTitle); }); test(`check if collaborated goal is visible in User ${receiver}'s MyGoal`, async () => { @@ -110,7 +122,7 @@ test.describe("Goal Sharing Feature", () => { ({ sharer, receiverFirst, receiverSecond, sharerPage, receiverPageFirst, receiverPageSecond }) => { test(`goal update by ${sharer}: edit goal in User ${sharer}`, async () => { await goToMyGoalsPageFlow(sharerPage()); - await goalActionFlow(sharerPage(), "Edit"); + await goalActionFlow(sharerPage(), "Edit", currentGoalTitle); await sharerPage().locator(".header-title").locator("input").fill(`${currentGoalTitle} edited by ${sharer}`); await sharerPage().locator(".action-btn-container").locator(".action-btn").click(); currentGoalTitle = await sharerPage().locator(".goal-title").first().locator("span").innerText(); diff --git a/playwright/utils/collaboration-feature-utils.ts b/playwright/utils/collaboration-feature-utils.ts index 2fbcce310..af395c99f 100644 --- a/playwright/utils/collaboration-feature-utils.ts +++ b/playwright/utils/collaboration-feature-utils.ts @@ -6,8 +6,21 @@ export async function createUserContextAndPage(browser: Browser) { return { context, page }; } -export async function goalActionFlow(page: Page, action: string) { - await page.locator(".goal-dd-outer").first().click(); +export async function goalActionFlow(page: Page, action: string, goalTitle: string) { + const goalDiv = await page.locator(".user-goal-main").filter({ hasText: new RegExp(`^${goalTitle}$`) }); + console.log(goalDiv); + + // Find the .goal-dd-outer associated with the goal title 'Test Goal' + const goalDropdown = await page + .locator(".user-goal-main") + .filter({ + has: page.locator('.goal-title:has-text("Test Goal")'), + }) + .locator(".goal-dd-outer"); + + // Click the specific .goal-dd-outer + await goalDropdown.click(); + await page .locator("div") .filter({ hasText: new RegExp(`^${action}$`) }) @@ -15,44 +28,53 @@ export async function goalActionFlow(page: Page, action: string) { .click({ force: true }); } -export async function goToShareGoalModalFlow(page: Page) { - await goalActionFlow(page, "Share"); +export async function goToShareGoalModalFlow(page: Page, goalTitle: string) { + await goalActionFlow(page, "Share", goalTitle); } export async function waitForResponseConfirmation( page: Page, urlContains: string, maxRetries: number = 3, - retryDelay: number = 3000, + retryDelay: number = 2000, ): Promise { + let response; for (let attempt = 1; attempt <= maxRetries; attempt++) { try { if (attempt > 1) { - await page.reload(); + page.reload(); } - const response = await page.waitForResponse((res) => res.url().includes(urlContains) && res.status() === 200); + response = await page.waitForResponse((res) => res.url().includes(urlContains) && res.status() === 200, { + timeout: 5000, + }); console.log(`Success on attempt ${attempt}`); - console.log(`Response: ${JSON.stringify(response)}`); - return; + const responseBody = await response.text(); + console.log(`Response status: ${response.status()}`); + console.log(`Response body: ${responseBody}`); + + return; // Exit after success } catch (error) { + console.warn(`Attempt ${attempt} failed. Retrying in ${retryDelay}ms...`); if (attempt === maxRetries) { - console.error(`All ${maxRetries} attempts failed. Last error: ${error.message}`); - throw new Error(`Failed to get response confirmation after ${maxRetries} attempts: ${error.message}`); + console.error(`Failed after ${maxRetries} attempts. Last error: ${error.message}`); + throw new Error(`Failed to get response confirmation: ${error.message}`); } - console.warn(`Attempt ${attempt} failed. Retrying in ${retryDelay}ms...`); + await page.waitForTimeout(retryDelay); } } } + export async function addContact( page: Page, contactName: string, + goalTitle: string, expectedApiResponse1: string, expectedApiResponse2: string, ): Promise { const apiServerUrl = "https://sfk3sq5mfzgfjfy3hytp4tmon40bbjpu.lambda-url.eu-west-1.on.aws/"; - await goToShareGoalModalFlow(page); + await goToShareGoalModalFlow(page, goalTitle); // Add contact flow await page.getByRole("button", { name: "add contact", exact: true }).click(); @@ -67,8 +89,8 @@ export async function addContact( return page.evaluate("navigator.clipboard.readText()"); } -export async function collaborateFlow(page: Page) { - await goalActionFlow(page, "Collaborate"); +export async function collaborateFlow(page: Page, goalTitle: string) { + await goalActionFlow(page, "Collaborate", goalTitle); await page.getByRole("button", { name: "Collaborate on goal" }).click(); } @@ -97,7 +119,6 @@ export async function verifyUpdatedGoal( await Promise.all([ page.waitForResponse((res) => res.status() === 200 && res.url().includes(apiUrlGoal), { timeout: 10000 }), ]); - await page.getByRole("button", { name: "Goals" }).click(); await page.locator(".goal-dd-outer").first().click(); From 6c791f9255cfdfdaf98b3852bce1cdbb9bc0a02f Mon Sep 17 00:00:00 2001 From: Vinay Badgujar Date: Sat, 5 Oct 2024 16:11:34 +0530 Subject: [PATCH 14/27] add network idles --- .../goal-collaboration-feature.spec.ts | 18 +++++++++++++-- .../utils/collaboration-feature-utils.ts | 22 +++++++++---------- 2 files changed, 27 insertions(+), 13 deletions(-) diff --git a/playwright/tests/collaboration-feature/goal-collaboration-feature.spec.ts b/playwright/tests/collaboration-feature/goal-collaboration-feature.spec.ts index d8a44d4d5..57ba9118a 100644 --- a/playwright/tests/collaboration-feature/goal-collaboration-feature.spec.ts +++ b/playwright/tests/collaboration-feature/goal-collaboration-feature.spec.ts @@ -108,13 +108,20 @@ test.describe("Goal Sharing Feature", () => { }); test(`initiate collaboration between User ${sharer} and User ${receiver}`, async () => { + await receiverPage().waitForLoadState("networkidle"); await collaborateFlow(receiverPage(), currentGoalTitle); }); test(`check if collaborated goal is visible in User ${receiver}'s MyGoal`, async () => { await receiverPage().goto("http://127.0.0.1:3000/"); await receiverPage().getByRole("button", { name: "Goals" }).click(); - await expect(receiverPage().locator(".goal-title").first().locator("span")).toContainText(currentGoalTitle); + const userGoalWithContact = receiverPage() + .locator(".user-goal-dark") + .filter({ + has: receiverPage().locator(".contact-icon"), + }); + + await expect(userGoalWithContact.locator(".goal-title span")).toContainText(currentGoalTitle); }); }); @@ -125,7 +132,14 @@ test.describe("Goal Sharing Feature", () => { await goalActionFlow(sharerPage(), "Edit", currentGoalTitle); await sharerPage().locator(".header-title").locator("input").fill(`${currentGoalTitle} edited by ${sharer}`); await sharerPage().locator(".action-btn-container").locator(".action-btn").click(); - currentGoalTitle = await sharerPage().locator(".goal-title").first().locator("span").innerText(); + // Locate the .goal-title span within the user-goal-dark div that also contains the .contact-icon + currentGoalTitle = await sharerPage() + .locator(".user-goal-dark") + .filter({ + has: sharerPage().locator(".contact-icon"), + }) + .locator(".goal-title span") + .innerText(); }); test(`goal update by ${sharer}: check if User ${receiverFirst} received updated goal from User ${sharer}`, async () => { diff --git a/playwright/utils/collaboration-feature-utils.ts b/playwright/utils/collaboration-feature-utils.ts index af395c99f..0d4eb5c50 100644 --- a/playwright/utils/collaboration-feature-utils.ts +++ b/playwright/utils/collaboration-feature-utils.ts @@ -10,7 +10,6 @@ export async function goalActionFlow(page: Page, action: string, goalTitle: stri const goalDiv = await page.locator(".user-goal-main").filter({ hasText: new RegExp(`^${goalTitle}$`) }); console.log(goalDiv); - // Find the .goal-dd-outer associated with the goal title 'Test Goal' const goalDropdown = await page .locator(".user-goal-main") .filter({ @@ -18,7 +17,6 @@ export async function goalActionFlow(page: Page, action: string, goalTitle: stri }) .locator(".goal-dd-outer"); - // Click the specific .goal-dd-outer await goalDropdown.click(); await page @@ -53,7 +51,7 @@ export async function waitForResponseConfirmation( console.log(`Response status: ${response.status()}`); console.log(`Response body: ${responseBody}`); - return; // Exit after success + return; } catch (error) { console.warn(`Attempt ${attempt} failed. Retrying in ${retryDelay}ms...`); if (attempt === maxRetries) { @@ -66,13 +64,7 @@ export async function waitForResponseConfirmation( } } -export async function addContact( - page: Page, - contactName: string, - goalTitle: string, - expectedApiResponse1: string, - expectedApiResponse2: string, -): Promise { +export async function addContact(page: Page, contactName: string, goalTitle: string): Promise { const apiServerUrl = "https://sfk3sq5mfzgfjfy3hytp4tmon40bbjpu.lambda-url.eu-west-1.on.aws/"; await goToShareGoalModalFlow(page, goalTitle); @@ -120,7 +112,15 @@ export async function verifyUpdatedGoal( page.waitForResponse((res) => res.status() === 200 && res.url().includes(apiUrlGoal), { timeout: 10000 }), ]); await page.getByRole("button", { name: "Goals" }).click(); - await page.locator(".goal-dd-outer").first().click(); + await page.waitForLoadState("networkidle"); + const goalDropdownWithContact = page + .locator(".user-goal-dark") + .filter({ + has: page.locator(".contact-icon"), + }) + .locator(".goal-dd-outer"); + + await goalDropdownWithContact.click(); await page.waitForSelector(`text=${expectedGoalTitle}`, { timeout: 10000 }); From cf8adddd678fd0580481a536dacee83425af1318 Mon Sep 17 00:00:00 2001 From: Vinay Badgujar Date: Sat, 5 Oct 2024 16:36:04 +0530 Subject: [PATCH 15/27] check for notification symbol --- .../goal-collaboration-feature.spec.ts | 4 ++-- playwright/utils/collaboration-feature-utils.ts | 6 ++++-- src/common/NotificationSymbol.tsx | 1 + 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/playwright/tests/collaboration-feature/goal-collaboration-feature.spec.ts b/playwright/tests/collaboration-feature/goal-collaboration-feature.spec.ts index 57ba9118a..c5723894c 100644 --- a/playwright/tests/collaboration-feature/goal-collaboration-feature.spec.ts +++ b/playwright/tests/collaboration-feature/goal-collaboration-feature.spec.ts @@ -84,7 +84,7 @@ test.describe("Goal Sharing Feature", () => { await titleInputContainer.fill(currentGoalTitle); await titleInputContainer.press("Enter"); } - invitationLink = await addContact(sharerPage(), receiver, currentGoalTitle, "relId", "relationshipId"); + invitationLink = await addContact(sharerPage(), receiver, currentGoalTitle); await goToMyGoalsPageFlow(sharerPage()); await goToShareGoalModalFlow(sharerPage(), currentGoalTitle); }); @@ -108,7 +108,7 @@ test.describe("Goal Sharing Feature", () => { }); test(`initiate collaboration between User ${sharer} and User ${receiver}`, async () => { - await receiverPage().waitForLoadState("networkidle"); + await receiverPage().waitForLoadState("networkidle", { timeout: 5000 }); await collaborateFlow(receiverPage(), currentGoalTitle); }); diff --git a/playwright/utils/collaboration-feature-utils.ts b/playwright/utils/collaboration-feature-utils.ts index 0d4eb5c50..0fc8baf9f 100644 --- a/playwright/utils/collaboration-feature-utils.ts +++ b/playwright/utils/collaboration-feature-utils.ts @@ -83,6 +83,8 @@ export async function addContact(page: Page, contactName: string, goalTitle: str export async function collaborateFlow(page: Page, goalTitle: string) { await goalActionFlow(page, "Collaborate", goalTitle); + await expect(page.getByRole("button", { name: "Collaborate on goal" })).toBeVisible(); + await page.getByRole("button", { name: "Collaborate on goal" }).click(); } @@ -112,14 +114,14 @@ export async function verifyUpdatedGoal( page.waitForResponse((res) => res.status() === 200 && res.url().includes(apiUrlGoal), { timeout: 10000 }), ]); await page.getByRole("button", { name: "Goals" }).click(); - await page.waitForLoadState("networkidle"); + await page.waitForLoadState("networkidle", { timeout: 5000 }); const goalDropdownWithContact = page .locator(".user-goal-dark") .filter({ has: page.locator(".contact-icon"), }) .locator(".goal-dd-outer"); - + await expect(goalDropdownWithContact.getByTestId("notification-dot")).toBeVisible(); await goalDropdownWithContact.click(); await page.waitForSelector(`text=${expectedGoalTitle}`, { timeout: 10000 }); diff --git a/src/common/NotificationSymbol.tsx b/src/common/NotificationSymbol.tsx index fa3b81ff4..5181d6e83 100644 --- a/src/common/NotificationSymbol.tsx +++ b/src/common/NotificationSymbol.tsx @@ -2,6 +2,7 @@ import React from "react"; const NotificationSymbol = ({ color }: { color: string }) => (
Date: Sat, 5 Oct 2024 17:10:13 +0530 Subject: [PATCH 16/27] add console logs --- .../goal-collaboration-feature.spec.ts | 46 +++++++++++++++---- .../utils/collaboration-feature-utils.ts | 28 +++++++++-- 2 files changed, 59 insertions(+), 15 deletions(-) diff --git a/playwright/tests/collaboration-feature/goal-collaboration-feature.spec.ts b/playwright/tests/collaboration-feature/goal-collaboration-feature.spec.ts index c5723894c..47219d95d 100644 --- a/playwright/tests/collaboration-feature/goal-collaboration-feature.spec.ts +++ b/playwright/tests/collaboration-feature/goal-collaboration-feature.spec.ts @@ -9,6 +9,7 @@ import { goToShareGoalModalFlow, goalActionFlow, verifyUpdatedGoal, + waitForPageLoad, waitForResponseConfirmation, } from "../../utils/collaboration-feature-utils"; @@ -22,21 +23,29 @@ test.describe("Goal Sharing Feature", () => { let currentGoalTitle = "Test Goal"; test.beforeAll(async ({ browser }) => { + console.log("Setting up users A, B, and C pages..."); ({ page: userAPage } = await createUserContextAndPage(browser)); ({ page: userBPage } = await createUserContextAndPage(browser)); ({ page: userCPage } = await createUserContextAndPage(browser)); + + console.log("Navigating User A to the main page..."); await userAPage.goto("http://127.0.0.1:3000/"); await userAPage.getByText("English").click(); await userAPage.getByRole("button", { name: "Continue zinzen faq" }).click(); + + console.log("Navigating User B to the main page..."); await userBPage.goto("http://127.0.0.1:3000/"); await userBPage.getByText("English").click(); await userBPage.getByRole("button", { name: "Continue zinzen faq" }).click(); + + console.log("Navigating User C to the main page..."); await userCPage.goto("http://127.0.0.1:3000/"); await userCPage.getByText("English").click(); await userCPage.getByRole("button", { name: "Continue zinzen faq" }).click(); }); test.afterAll(async () => { + console.log("Closing all user pages..."); await userAPage.close(); await userBPage.close(); await userCPage.close(); @@ -76,30 +85,41 @@ test.describe("Goal Sharing Feature", () => { userCollaborationScenarios.forEach(({ sharer, receiver, sharerPage, receiverPage }) => { test(`from User ${sharer} share invitation to User ${receiver}`, async () => { + console.log(`User ${sharer} is navigating to their goals page...`); await goToMyGoalsPageFlow(sharerPage()); - if (sharer === "A") { - await sharerPage().getByRole("button", { name: "add goal | add feeling | add group", exact: true }).click({}); + if (sharer === "A") { + console.log(`User ${sharer} is creating a new goal titled "${currentGoalTitle}"...`); + await sharerPage().getByRole("button", { name: "add goal | add feeling | add group", exact: true }).click(); const titleInputContainer = sharerPage().getByPlaceholder("Goal title"); await titleInputContainer.fill(currentGoalTitle); await titleInputContainer.press("Enter"); } + + console.log(`User ${sharer} is adding User ${receiver} as a contact...`); invitationLink = await addContact(sharerPage(), receiver, currentGoalTitle); + + console.log(`User ${sharer} is navigating to their goals page again...`); await goToMyGoalsPageFlow(sharerPage()); + + console.log(`User ${sharer} is opening the share goal modal for "${currentGoalTitle}"...`); await goToShareGoalModalFlow(sharerPage(), currentGoalTitle); }); test(`from User ${receiver} accept invitation of User ${sharer}`, async () => { + console.log(`User ${receiver} is accepting the invitation from User ${sharer}...`); await acceptContactInvitation(receiverPage(), invitationLink, receiver); await waitForResponseConfirmation(receiverPage(), API_SERVER_URL); }); test(`share goal from User ${receiver} to User ${sharer}`, async () => { + console.log(`User ${sharer} is sharing the goal with User ${receiver}...`); await sharerPage().getByRole("button", { name: receiver, exact: true }).click(); await sharerPage().waitForSelector(".ant-notification-notice"); }); - test(`check whether shared goal is visible in User ${receiver}'s patner goal`, async () => { + test(`check whether shared goal is visible in User ${receiver}'s partner goal`, async () => { + console.log(`User ${receiver} is reloading the page to check for shared goal visibility...`); await receiverPage().reload(); await waitForResponseConfirmation(receiverPage(), API_SERVER_URL_GOAL); await receiverPage().getByRole("img", { name: "ZinZen" }).click(); @@ -108,11 +128,12 @@ test.describe("Goal Sharing Feature", () => { }); test(`initiate collaboration between User ${sharer} and User ${receiver}`, async () => { - await receiverPage().waitForLoadState("networkidle", { timeout: 5000 }); + console.log(`Initiating collaboration between User ${sharer} and User ${receiver}...`); await collaborateFlow(receiverPage(), currentGoalTitle); }); test(`check if collaborated goal is visible in User ${receiver}'s MyGoal`, async () => { + console.log(`Checking if collaborated goal is visible in User ${receiver}'s MyGoal...`); await receiverPage().goto("http://127.0.0.1:3000/"); await receiverPage().getByRole("button", { name: "Goals" }).click(); const userGoalWithContact = receiverPage() @@ -120,7 +141,6 @@ test.describe("Goal Sharing Feature", () => { .filter({ has: receiverPage().locator(".contact-icon"), }); - await expect(userGoalWithContact.locator(".goal-title span")).toContainText(currentGoalTitle); }); }); @@ -128,11 +148,15 @@ test.describe("Goal Sharing Feature", () => { editAndConfirmScenarios.forEach( ({ sharer, receiverFirst, receiverSecond, sharerPage, receiverPageFirst, receiverPageSecond }) => { test(`goal update by ${sharer}: edit goal in User ${sharer}`, async () => { - await goToMyGoalsPageFlow(sharerPage()); - await goalActionFlow(sharerPage(), "Edit", currentGoalTitle); - await sharerPage().locator(".header-title").locator("input").fill(`${currentGoalTitle} edited by ${sharer}`); - await sharerPage().locator(".action-btn-container").locator(".action-btn").click(); - // Locate the .goal-title span within the user-goal-dark div that also contains the .contact-icon + console.log(`User ${sharer} is updating the goal "${currentGoalTitle}"...`); + await expect(async () => { + await goToMyGoalsPageFlow(sharerPage()); + await goalActionFlow(sharerPage(), "Edit", currentGoalTitle); + await sharerPage().locator(".header-title").locator("input").fill(`${currentGoalTitle} edited by ${sharer}`); + await sharerPage().locator(".action-btn-container").locator(".action-btn").click(); + }).toPass(); + + console.log(`Getting the updated goal title from User ${sharer}'s page...`); currentGoalTitle = await sharerPage() .locator(".user-goal-dark") .filter({ @@ -143,10 +167,12 @@ test.describe("Goal Sharing Feature", () => { }); test(`goal update by ${sharer}: check if User ${receiverFirst} received updated goal from User ${sharer}`, async () => { + console.log(`Checking if User ${receiverFirst} received the updated goal from User ${sharer}...`); await verifyUpdatedGoal(receiverPageFirst(), currentGoalTitle, API_SERVER_URL_GOAL); }); test(`goal update by ${sharer}: check if User ${receiverSecond} received updated goal from User ${sharer}`, async () => { + console.log(`Checking if User ${receiverSecond} received the updated goal from User ${sharer}...`); await verifyUpdatedGoal(receiverPageSecond(), currentGoalTitle, API_SERVER_URL_GOAL); }); }, diff --git a/playwright/utils/collaboration-feature-utils.ts b/playwright/utils/collaboration-feature-utils.ts index 0fc8baf9f..0a2c2b306 100644 --- a/playwright/utils/collaboration-feature-utils.ts +++ b/playwright/utils/collaboration-feature-utils.ts @@ -82,10 +82,11 @@ export async function addContact(page: Page, contactName: string, goalTitle: str } export async function collaborateFlow(page: Page, goalTitle: string) { - await goalActionFlow(page, "Collaborate", goalTitle); - await expect(page.getByRole("button", { name: "Collaborate on goal" })).toBeVisible(); - - await page.getByRole("button", { name: "Collaborate on goal" }).click(); + await expect(async () => { + await goalActionFlow(page, "Collaborate", goalTitle); + await expect(page.getByRole("button", { name: "Collaborate on goal" })).toBeVisible(); + await page.getByRole("button", { name: "Collaborate on goal" }).click(); + }).toPass(); } export async function acceptContactInvitation(page: Page, invitationLink: string, patnerName: string) { @@ -114,7 +115,6 @@ export async function verifyUpdatedGoal( page.waitForResponse((res) => res.status() === 200 && res.url().includes(apiUrlGoal), { timeout: 10000 }), ]); await page.getByRole("button", { name: "Goals" }).click(); - await page.waitForLoadState("networkidle", { timeout: 5000 }); const goalDropdownWithContact = page .locator(".user-goal-dark") .filter({ @@ -140,3 +140,21 @@ export async function verifyUpdatedGoal( } } } + +export async function waitForPageLoad(page: Page, retries: number = 3, retryDelay: number = 3000) { + for (let attempt = 1; attempt <= retries; attempt++) { + try { + console.log(`Attempting to wait for networkidle state (Attempt ${attempt})...`); + await page.waitForLoadState("networkidle", { timeout: 5000 }); + console.log("Page load state reached networkidle successfully."); + return; // Success, exit the function + } catch (error) { + console.warn(`Page load attempt ${attempt} failed. Retrying in ${retryDelay}ms...`); + if (attempt === retries) { + console.error(`Failed after ${retries} attempts: ${error.message}`); + throw new Error(`Failed to wait for page load state: ${error.message}`); + } + await page.waitForTimeout(retryDelay); // Wait before retrying + } + } +} From 4f2a7bb96ce07be9836e7b3bee4f626072e5b235 Mon Sep 17 00:00:00 2001 From: Vinay Badgujar Date: Sat, 5 Oct 2024 17:26:11 +0530 Subject: [PATCH 17/27] add more console log --- .../goal-collaboration-feature.spec.ts | 10 ++++- .../utils/collaboration-feature-utils.ts | 44 ++++++++++++++++--- 2 files changed, 47 insertions(+), 7 deletions(-) diff --git a/playwright/tests/collaboration-feature/goal-collaboration-feature.spec.ts b/playwright/tests/collaboration-feature/goal-collaboration-feature.spec.ts index 47219d95d..5d90741a6 100644 --- a/playwright/tests/collaboration-feature/goal-collaboration-feature.spec.ts +++ b/playwright/tests/collaboration-feature/goal-collaboration-feature.spec.ts @@ -114,8 +114,14 @@ test.describe("Goal Sharing Feature", () => { test(`share goal from User ${receiver} to User ${sharer}`, async () => { console.log(`User ${sharer} is sharing the goal with User ${receiver}...`); - await sharerPage().getByRole("button", { name: receiver, exact: true }).click(); - await sharerPage().waitForSelector(".ant-notification-notice"); + await goToMyGoalsPageFlow(sharerPage()); + + console.log(`User ${sharer} is opening the share goal modal for "${currentGoalTitle}"...`); + await goToShareGoalModalFlow(sharerPage(), currentGoalTitle); + await expect(async () => { + await sharerPage().getByRole("button", { name: receiver, exact: true }).click(); + await sharerPage().waitForLoadState("networkidle"); + }).toPass(); }); test(`check whether shared goal is visible in User ${receiver}'s partner goal`, async () => { diff --git a/playwright/utils/collaboration-feature-utils.ts b/playwright/utils/collaboration-feature-utils.ts index 0a2c2b306..6b4f2601e 100644 --- a/playwright/utils/collaboration-feature-utils.ts +++ b/playwright/utils/collaboration-feature-utils.ts @@ -1,14 +1,17 @@ import { Browser, Page, expect } from "@playwright/test"; export async function createUserContextAndPage(browser: Browser) { + console.log("Creating a new user context and page..."); const context = await browser.newContext(); const page = await context.newPage(); + console.log("User context and page created successfully."); return { context, page }; } export async function goalActionFlow(page: Page, action: string, goalTitle: string) { + console.log(`Executing action "${action}" on goal titled "${goalTitle}"...`); const goalDiv = await page.locator(".user-goal-main").filter({ hasText: new RegExp(`^${goalTitle}$`) }); - console.log(goalDiv); + console.log("Located goal div:", goalDiv); const goalDropdown = await page .locator(".user-goal-main") @@ -17,8 +20,10 @@ export async function goalActionFlow(page: Page, action: string, goalTitle: stri }) .locator(".goal-dd-outer"); + console.log("Clicking on the goal dropdown..."); await goalDropdown.click(); + console.log(`Clicking on the action "${action}"...`); await page .locator("div") .filter({ hasText: new RegExp(`^${action}$`) }) @@ -27,6 +32,7 @@ export async function goalActionFlow(page: Page, action: string, goalTitle: stri } export async function goToShareGoalModalFlow(page: Page, goalTitle: string) { + console.log(`Navigating to Share Goal modal for goal titled "${goalTitle}"...`); await goalActionFlow(page, "Share", goalTitle); } @@ -36,10 +42,13 @@ export async function waitForResponseConfirmation( maxRetries: number = 3, retryDelay: number = 2000, ): Promise { + console.log(`Waiting for response confirmation for URL containing "${urlContains}"...`); let response; for (let attempt = 1; attempt <= maxRetries; attempt++) { + console.log(`Attempt ${attempt}...`); try { if (attempt > 1) { + console.log("Reloading the page..."); page.reload(); } response = await page.waitForResponse((res) => res.url().includes(urlContains) && res.status() === 200, { @@ -65,38 +74,54 @@ export async function waitForResponseConfirmation( } export async function addContact(page: Page, contactName: string, goalTitle: string): Promise { + console.log(`Adding contact "${contactName}" to goal "${goalTitle}"...`); const apiServerUrl = "https://sfk3sq5mfzgfjfy3hytp4tmon40bbjpu.lambda-url.eu-west-1.on.aws/"; await goToShareGoalModalFlow(page, goalTitle); - // Add contact flow + console.log("Opening 'Add contact' modal..."); await page.getByRole("button", { name: "add contact", exact: true }).click(); await page.getByPlaceholder("Name").click(); await page.getByPlaceholder("Name").fill(contactName); await page.getByRole("button", { name: "add contact Share invitation" }).click(); + + console.log("Waiting for response confirmation after adding contact..."); await waitForResponseConfirmation(page, apiServerUrl); + + console.log("Navigating back and clicking on the contact..."); await page.goBack(); await page.getByRole("button", { name: contactName.slice(0, 1), exact: true }).click(); + + console.log("Waiting for confirmation of contact invitation..."); await waitForResponseConfirmation(page, apiServerUrl); await page.waitForSelector(".ant-notification-notice"); + + console.log("Reading invitation link from clipboard..."); return page.evaluate("navigator.clipboard.readText()"); } export async function collaborateFlow(page: Page, goalTitle: string) { + console.log(`Initiating collaboration on goal titled "${goalTitle}"...`); await expect(async () => { await goalActionFlow(page, "Collaborate", goalTitle); await expect(page.getByRole("button", { name: "Collaborate on goal" })).toBeVisible(); + + console.log("Clicking 'Collaborate on goal'..."); await page.getByRole("button", { name: "Collaborate on goal" }).click(); }).toPass(); } -export async function acceptContactInvitation(page: Page, invitationLink: string, patnerName: string) { +export async function acceptContactInvitation(page: Page, invitationLink: string, partnerName: string) { + console.log(`Accepting contact invitation using link: ${invitationLink}`); await page.goto(`${invitationLink}`); + + console.log(`Filling in partner name "${partnerName}"...`); await page.getByPlaceholder("Contact name").click(); - await page.getByPlaceholder("Contact name").fill(patnerName); + await page.getByPlaceholder("Contact name").fill(partnerName); await page.getByRole("button", { name: "Add to my contacts" }).click(); } export async function goToMyGoalsPageFlow(page: Page) { + console.log("Navigating to 'My Goals' page..."); await page.goto("http://127.0.0.1:3000/"); await page.getByRole("button", { name: "Goals" }).click(); } @@ -108,32 +133,41 @@ export async function verifyUpdatedGoal( maxRetries: number = 3, retryDelay: number = 2000, ): Promise { + console.log(`Verifying updated goal titled "${expectedGoalTitle}"...`); for (let attempt = 1; attempt <= maxRetries; attempt++) { + console.log(`Attempt ${attempt}...`); try { await page.goto("http://127.0.0.1:3000/"); await Promise.all([ page.waitForResponse((res) => res.status() === 200 && res.url().includes(apiUrlGoal), { timeout: 10000 }), ]); await page.getByRole("button", { name: "Goals" }).click(); + const goalDropdownWithContact = page .locator(".user-goal-dark") .filter({ has: page.locator(".contact-icon"), }) .locator(".goal-dd-outer"); + + console.log("Checking for notification dot..."); await expect(goalDropdownWithContact.getByTestId("notification-dot")).toBeVisible(); await goalDropdownWithContact.click(); + console.log(`Waiting for goal titled "${expectedGoalTitle}" to be visible...`); await page.waitForSelector(`text=${expectedGoalTitle}`, { timeout: 10000 }); + console.log("Applying changes..."); await page.getByRole("button", { name: "add changes Make all checked" }).click(); + console.log(`Verifying if the goal "${expectedGoalTitle}" is updated successfully...`); await page.waitForSelector(`text=${expectedGoalTitle}`, { timeout: 10000 }); return; } catch (error) { if (attempt === maxRetries) { - throw new Error(`Failed to verify updated goal after ${maxRetries} attempts: ${error.message}`); + console.error(`Failed to verify updated goal after ${maxRetries} attempts: ${error.message}`); + throw new Error(`Failed to verify updated goal: ${error.message}`); } console.warn(`Attempt ${attempt} failed. Retrying in ${retryDelay}ms...`); await page.waitForTimeout(retryDelay); From abd24fd1e946e9f320b4ecca19d9231666adacff Mon Sep 17 00:00:00 2001 From: Vinay Badgujar Date: Sat, 5 Oct 2024 17:37:20 +0530 Subject: [PATCH 18/27] await for modal to display --- playwright/utils/collaboration-feature-utils.ts | 2 +- src/common/ZModal.tsx | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/playwright/utils/collaboration-feature-utils.ts b/playwright/utils/collaboration-feature-utils.ts index 6b4f2601e..f65441dac 100644 --- a/playwright/utils/collaboration-feature-utils.ts +++ b/playwright/utils/collaboration-feature-utils.ts @@ -22,7 +22,7 @@ export async function goalActionFlow(page: Page, action: string, goalTitle: stri console.log("Clicking on the goal dropdown..."); await goalDropdown.click(); - + await expect(page.getByTestId("zmodal")).toBeVisible(); console.log(`Clicking on the action "${action}"...`); await page .locator("div") diff --git a/src/common/ZModal.tsx b/src/common/ZModal.tsx index 25ebb14f5..fc5a39ca2 100644 --- a/src/common/ZModal.tsx +++ b/src/common/ZModal.tsx @@ -29,6 +29,7 @@ const ZModal: React.FC = ({ children, type, open, onCancel, width, styles={{ mask: maskStyle }} width={width} style={style} + data-testid="zmodal" > {children} From b38620d5f19e562c852ad41cb8636ea6caf6d9b8 Mon Sep 17 00:00:00 2001 From: Vinay Badgujar Date: Sat, 5 Oct 2024 17:41:37 +0530 Subject: [PATCH 19/27] fix: replace isvisible with inviewport --- playwright/utils/collaboration-feature-utils.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/playwright/utils/collaboration-feature-utils.ts b/playwright/utils/collaboration-feature-utils.ts index f65441dac..14ba050b3 100644 --- a/playwright/utils/collaboration-feature-utils.ts +++ b/playwright/utils/collaboration-feature-utils.ts @@ -22,7 +22,7 @@ export async function goalActionFlow(page: Page, action: string, goalTitle: stri console.log("Clicking on the goal dropdown..."); await goalDropdown.click(); - await expect(page.getByTestId("zmodal")).toBeVisible(); + await expect(page.getByTestId("zmodal")).toBeInViewport(); console.log(`Clicking on the action "${action}"...`); await page .locator("div") From adb862a01dc416681853478c7e21e520d46c3c89 Mon Sep 17 00:00:00 2001 From: Vinay Badgujar Date: Sat, 5 Oct 2024 17:53:12 +0530 Subject: [PATCH 20/27] small fix --- .../collaboration-feature/goal-collaboration-feature.spec.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/playwright/tests/collaboration-feature/goal-collaboration-feature.spec.ts b/playwright/tests/collaboration-feature/goal-collaboration-feature.spec.ts index 5d90741a6..6e0c0f12c 100644 --- a/playwright/tests/collaboration-feature/goal-collaboration-feature.spec.ts +++ b/playwright/tests/collaboration-feature/goal-collaboration-feature.spec.ts @@ -145,7 +145,7 @@ test.describe("Goal Sharing Feature", () => { const userGoalWithContact = receiverPage() .locator(".user-goal-dark") .filter({ - has: receiverPage().locator(".contact-icon"), + has: receiverPage().locator(".contact-button"), }); await expect(userGoalWithContact.locator(".goal-title span")).toContainText(currentGoalTitle); }); @@ -166,7 +166,7 @@ test.describe("Goal Sharing Feature", () => { currentGoalTitle = await sharerPage() .locator(".user-goal-dark") .filter({ - has: sharerPage().locator(".contact-icon"), + has: sharerPage().locator(".contact-button"), }) .locator(".goal-title span") .innerText(); From b571ceecfb9120dbf7964df7f1e5ff8a63c551ab Mon Sep 17 00:00:00 2001 From: Vinay Badgujar Date: Sat, 5 Oct 2024 18:05:45 +0530 Subject: [PATCH 21/27] small fix --- .../goal-collaboration-feature.spec.ts | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/playwright/tests/collaboration-feature/goal-collaboration-feature.spec.ts b/playwright/tests/collaboration-feature/goal-collaboration-feature.spec.ts index 6e0c0f12c..242aca8bc 100644 --- a/playwright/tests/collaboration-feature/goal-collaboration-feature.spec.ts +++ b/playwright/tests/collaboration-feature/goal-collaboration-feature.spec.ts @@ -121,7 +121,9 @@ test.describe("Goal Sharing Feature", () => { await expect(async () => { await sharerPage().getByRole("button", { name: receiver, exact: true }).click(); await sharerPage().waitForLoadState("networkidle"); - }).toPass(); + }).toPass({ + timeout: 2000, + }); }); test(`check whether shared goal is visible in User ${receiver}'s partner goal`, async () => { @@ -142,12 +144,8 @@ test.describe("Goal Sharing Feature", () => { console.log(`Checking if collaborated goal is visible in User ${receiver}'s MyGoal...`); await receiverPage().goto("http://127.0.0.1:3000/"); await receiverPage().getByRole("button", { name: "Goals" }).click(); - const userGoalWithContact = receiverPage() - .locator(".user-goal-dark") - .filter({ - has: receiverPage().locator(".contact-button"), - }); - await expect(userGoalWithContact.locator(".goal-title span")).toContainText(currentGoalTitle); + + await expect(receiverPage().locator(".goal-title span").first()).toContainText(currentGoalTitle); }); }); From 4560c5e2fb33c4a2aab7eff806cf5a1b182e07de Mon Sep 17 00:00:00 2001 From: Vinay Badgujar Date: Sat, 5 Oct 2024 19:08:28 +0530 Subject: [PATCH 22/27] remove: dead function --- .../utils/collaboration-feature-utils.ts | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/playwright/utils/collaboration-feature-utils.ts b/playwright/utils/collaboration-feature-utils.ts index 14ba050b3..678e02a2c 100644 --- a/playwright/utils/collaboration-feature-utils.ts +++ b/playwright/utils/collaboration-feature-utils.ts @@ -174,21 +174,3 @@ export async function verifyUpdatedGoal( } } } - -export async function waitForPageLoad(page: Page, retries: number = 3, retryDelay: number = 3000) { - for (let attempt = 1; attempt <= retries; attempt++) { - try { - console.log(`Attempting to wait for networkidle state (Attempt ${attempt})...`); - await page.waitForLoadState("networkidle", { timeout: 5000 }); - console.log("Page load state reached networkidle successfully."); - return; // Success, exit the function - } catch (error) { - console.warn(`Page load attempt ${attempt} failed. Retrying in ${retryDelay}ms...`); - if (attempt === retries) { - console.error(`Failed after ${retries} attempts: ${error.message}`); - throw new Error(`Failed to wait for page load state: ${error.message}`); - } - await page.waitForTimeout(retryDelay); // Wait before retrying - } - } -} From 31cefde77dc374146d7094b15563305255f494c2 Mon Sep 17 00:00:00 2001 From: Vinay Badgujar Date: Sun, 6 Oct 2024 13:13:29 +0530 Subject: [PATCH 23/27] edit: check for the updated goal in my goals container --- .../collaboration-feature/goal-collaboration-feature.spec.ts | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/playwright/tests/collaboration-feature/goal-collaboration-feature.spec.ts b/playwright/tests/collaboration-feature/goal-collaboration-feature.spec.ts index 242aca8bc..01eba22de 100644 --- a/playwright/tests/collaboration-feature/goal-collaboration-feature.spec.ts +++ b/playwright/tests/collaboration-feature/goal-collaboration-feature.spec.ts @@ -9,7 +9,6 @@ import { goToShareGoalModalFlow, goalActionFlow, verifyUpdatedGoal, - waitForPageLoad, waitForResponseConfirmation, } from "../../utils/collaboration-feature-utils"; @@ -122,7 +121,7 @@ test.describe("Goal Sharing Feature", () => { await sharerPage().getByRole("button", { name: receiver, exact: true }).click(); await sharerPage().waitForLoadState("networkidle"); }).toPass({ - timeout: 2000, + timeout: 10_000, }); }); @@ -145,7 +144,7 @@ test.describe("Goal Sharing Feature", () => { await receiverPage().goto("http://127.0.0.1:3000/"); await receiverPage().getByRole("button", { name: "Goals" }).click(); - await expect(receiverPage().locator(".goal-title span").first()).toContainText(currentGoalTitle); + await expect(receiverPage().locator(".my-goals-content").first()).toContainText(currentGoalTitle); }); }); From 396936f9e9d32fca615622fd299c1a14081cf266 Mon Sep 17 00:00:00 2001 From: Vinay Badgujar Date: Sun, 6 Oct 2024 13:24:28 +0530 Subject: [PATCH 24/27] add page reload --- .../collaboration-feature/goal-collaboration-feature.spec.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/playwright/tests/collaboration-feature/goal-collaboration-feature.spec.ts b/playwright/tests/collaboration-feature/goal-collaboration-feature.spec.ts index 01eba22de..dd1c0a7ac 100644 --- a/playwright/tests/collaboration-feature/goal-collaboration-feature.spec.ts +++ b/playwright/tests/collaboration-feature/goal-collaboration-feature.spec.ts @@ -143,7 +143,8 @@ test.describe("Goal Sharing Feature", () => { console.log(`Checking if collaborated goal is visible in User ${receiver}'s MyGoal...`); await receiverPage().goto("http://127.0.0.1:3000/"); await receiverPage().getByRole("button", { name: "Goals" }).click(); - + await receiverPage().reload(); + await receiverPage().waitForLoadState("networkidle"); await expect(receiverPage().locator(".my-goals-content").first()).toContainText(currentGoalTitle); }); }); From 8de42fd90e9056d605ea4f4de937c44977de3dbb Mon Sep 17 00:00:00 2001 From: Vinay Badgujar Date: Sun, 6 Oct 2024 13:47:08 +0530 Subject: [PATCH 25/27] fix: minor error related to navigation --- .../collaboration-feature/goal-collaboration-feature.spec.ts | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/playwright/tests/collaboration-feature/goal-collaboration-feature.spec.ts b/playwright/tests/collaboration-feature/goal-collaboration-feature.spec.ts index dd1c0a7ac..c74ed7013 100644 --- a/playwright/tests/collaboration-feature/goal-collaboration-feature.spec.ts +++ b/playwright/tests/collaboration-feature/goal-collaboration-feature.spec.ts @@ -141,10 +141,7 @@ test.describe("Goal Sharing Feature", () => { test(`check if collaborated goal is visible in User ${receiver}'s MyGoal`, async () => { console.log(`Checking if collaborated goal is visible in User ${receiver}'s MyGoal...`); - await receiverPage().goto("http://127.0.0.1:3000/"); - await receiverPage().getByRole("button", { name: "Goals" }).click(); - await receiverPage().reload(); - await receiverPage().waitForLoadState("networkidle"); + await goToMyGoalsPageFlow(receiverPage()); await expect(receiverPage().locator(".my-goals-content").first()).toContainText(currentGoalTitle); }); }); From c84045be49fee73b4afd25814b2a27664a8bd631 Mon Sep 17 00:00:00 2001 From: Vinay Badgujar Date: Sun, 6 Oct 2024 13:57:25 +0530 Subject: [PATCH 26/27] edit: click on partner goal switch mode button instead of navigating to home page after initiating collaboration --- .../collaboration-feature/goal-collaboration-feature.spec.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/playwright/tests/collaboration-feature/goal-collaboration-feature.spec.ts b/playwright/tests/collaboration-feature/goal-collaboration-feature.spec.ts index c74ed7013..1c055c133 100644 --- a/playwright/tests/collaboration-feature/goal-collaboration-feature.spec.ts +++ b/playwright/tests/collaboration-feature/goal-collaboration-feature.spec.ts @@ -141,7 +141,7 @@ test.describe("Goal Sharing Feature", () => { test(`check if collaborated goal is visible in User ${receiver}'s MyGoal`, async () => { console.log(`Checking if collaborated goal is visible in User ${receiver}'s MyGoal...`); - await goToMyGoalsPageFlow(receiverPage()); + await receiverPage().locator(".header-logo-wrapper").click(); await expect(receiverPage().locator(".my-goals-content").first()).toContainText(currentGoalTitle); }); }); From 979b8366b1dd523143fedc4ded1568b3a9d8166c Mon Sep 17 00:00:00 2001 From: Vinay Badgujar Date: Sun, 6 Oct 2024 14:26:13 +0530 Subject: [PATCH 27/27] move back to headless mode --- .github/workflows/playwright.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/playwright.yml b/.github/workflows/playwright.yml index 884700bb1..281239171 100644 --- a/.github/workflows/playwright.yml +++ b/.github/workflows/playwright.yml @@ -18,7 +18,7 @@ jobs: - name: Install Playwright Browsers run: npx playwright install --with-deps - name: Run Playwright tests - run: xvfb-run npx playwright test --headed + run: npx playwright test - uses: actions/upload-artifact@v4 if: ${{ !cancelled() }} with: