vasu31dev / playwright-ts-template

Playwright Typescript Automation testing framework Template is designed for Web (Desktop & Mobile), API, and Electron apps. Stable and Robust layer on top of Playwright with inbuilt Utilities, Linting, Logger, Web hooks, Github actions, Reports and much more
113 stars 5 forks source link

Inquiry Regarding Shared Page Usage in this Framework #23

Closed santanakrishnan closed 6 months ago

santanakrishnan commented 9 months ago

Hi, Vasudeva,

I'm writing to express my appreciation for your excellent framework.

I have a question regarding test execution isolation within the framework. While I understand the benefits of isolated tests, I'm interested in exploring the possibility of using the same page object across multiple tests in certain scenarios. Could you please provide guidance on how to achieve this effectively while maintaining test clarity and reliability?

Specifically, I'm interested in understanding:

Are there built-in mechanisms or best practices within the framework to support the use of same page for all the tests? I appreciate any insights you can offer on this matter.

Thank you for your time and continued support.

vasu31dev commented 9 months ago

Thank you for the kind words, @santanakrishnan!

To achieve sharing a page across multiple tests, you can add the shared-page-setup.ts file to the framework under the test-setup folder. Then, in the spec files where you want the page to be shared, import it using import { test } from 'test-setup/shared-page-setup' instead of import { test } from '@pagesetup'. This setup includes clearing cookies after each test to ensure a clean state. However, if maintaining the session state is necessary for your tests, you have the option to remove the clearCookies code. Just ensure you manually clear any logged-in sessions at the end of each test if doing so. Here's how you can set it up:

import { Page, test as baseTest, expect } from '@playwright/test';
import { setPage } from 'vasu-playwright-utils';

let sharedPage: Page;

baseTest.beforeAll(async ({ browser }) => {
  sharedPage = await browser.newPage();
});

 // Clear cookies after each test
baseTest.afterEach(async ({}) => {
  await sharedPage.context().clearCookies();
});

export const test = baseTest.extend<{ testHook: void }>({
  testHook: [
    async ({}, use) => {
      setPage(sharedPage);
      await use();
    },
    { auto: true },
  ],
});

export { expect };

Please use this shared page approach sparingly to avoid complications in debugging arising from shared cookies or state between tests. Ensuring each test can run independently without relying on the state from a previous test is crucial for reliable, maintainable test suites.

Let me know if this helps, or if you have any further questions!

santanakrishnan commented 9 months ago

Thanks so much for the detailed explanation @vasu31dev , it really clarifies the steps involved in sharing a page across multiple tests. I actually have one more question regarding this. Now how to use beforeAll? For example i want to have the login script in beforeAll but i cant achieve this. It overrides the beforeAll which we use in shared-page-setup. the page was not initiated here

vasu31dev commented 9 months ago

Hi @santanakrishnan, It is better to use storageState(https://playwright.dev/docs/auth) for the Login script. Use beforeAll in the spec file for something like data setup, DB connection or API calls for the test.

vasu31dev commented 9 months ago

If you move the setPage(sharedPage) to beforeAll, then it will give you access to the page in the spec file inside the beforeAll test as well.

import { Page, test as baseTest, expect } from '@playwright/test';
import { setPage } from 'vasu-playwright-utils';

let sharedPage: Page;

baseTest.beforeAll(async ({ browser }) => {
  sharedPage = await browser.newPage();
   setPage(sharedPage);
});

 // Clear cookies after each test
baseTest.afterEach(async ({}) => {
  await sharedPage.context().clearCookies();
});

export const test = baseTest.extend<{ testHook: void }>({
  testHook: [
    async ({}, use) => {
      await use();
    },
    { auto: true },
  ],
});

export { expect };
santanakrishnan commented 9 months ago

Sorry. i am having trouble understanding this. My query here is as we have the beforeAll in shared-page-setup.ts, Can we use another beforeAll in spec file?

vasu31dev commented 9 months ago

After making the above change in shared-page-setup.ts, you can start using beforeAll in the spec file, as the same page will be reused between tests including beforeAll in the spec file. So add a beforeAll in spec file and it should work for you as the page is already initiated and ready to be used.

santanakrishnan commented 9 months ago

Thank you so much it works. Sorry to trouble you. One more doubt. I am using (https://playwright.dev/docs/auth) this way for login. But the session storages which i store manually are not captured in context().storagestate. Because of this even if i use storagestate in test file it is not in logged in state.

vasu31dev commented 8 months ago

@santanakrishnan Sorry for the late reply. I have added this spec file for you on how to use Storage State for your tests. Please update the necessary files like playwright.config.ts, login-storage-setup.ts for the login cookie to work properly. In case you face any issues please provide me a reproducible GitHub repo. https://github.com/vasu31dev/playwright-ts-template/blob/main/tests/specs/login-using-storage-states.spec.ts

vasu31dev commented 6 months ago

Closing the issue as all the questions are resolved and answered. @santanakrishnan Please open up a new issue if you have any more questions or defects.