Reputation: 489
I'm using Playwright with nodejs and I have grouped a couple of tests together like this
import { test, expect } from '@playwright/test';
test.describe('Add a simple invoice test', () => {
test('01.Login & add an invoice', async ({ page }) => {
await page.goto("https://someUrl.com");
await page.fill('input[id="email"]', "someEmailAddress");
await page.fill('input[ng-model="ctrl.user.password"]', "somePassword");
await page.click('button[id="login-btn"]');
});
test('02.Add an invoice', async ({ page }) => {
await page.click('[name="invoice"]');
await page.click('button[id="addInvoiceButton"]');
await page.click('a[ng-click="ctrl.goToAddInvoice()"]');
await page.fill('#invoiceTitle', Math.random().toString(36).substring(7));
await page.fill('#exampleInputAmount', "120");
await page.click("#invoiceCategory")
await page.fill("#invoiceCategory > input", "Car")
await page.keyboard.press("Enter");
await page.click('button[id="submitInvoiceButton"]');
});
});
The problem is that these 2 tests run in parallel whereas 02 is dependant on 01 since there's a required login.
How do I make 2 grouped tests run in the same context?
Upvotes: 20
Views: 33436
Reputation: 4171
In order to run grouped tests sequentially , you may use the test.describe.configure method. This ensures that tests within the group run one after another, in the order they are defined as below:
// Annotate tests as inter-dependent.
test.describe.configure({ mode: 'serial' });
test('runs first', async ({ page }) => {});
test('runs second', async ({ page }) => {});
Upvotes: 0
Reputation: 1787
The solution is very simple. It is executing as an independent test since you are passing {page} in each test, so if you want to use the same context for both the test you need to modify the test like below.
import { test, expect } from '@playwright/test';
test.describe('Add a simple invoice test', () => {
let page: Page;
test.beforeAll(async ({ browser }) => {
page = await browser.newPage();
});
test('01.Login & add an invoice', async () => { // do not pass page
await page.goto("https://someUrl.com");
await page.fill('input[id="email"]', "someEmailAddress");
await page.fill('input[ng-model="ctrl.user.password"]', "somePassword");
await page.click('button[id="login-btn"]');
});
test('02.Add an invoice', async () => { //do not pass page
await page.click('[name="invoice"]');
await page.click('button[id="addInvoiceButton"]');
await page.click('a[ng-click="ctrl.goToAddInvoice()"]');
await page.fill('#invoiceTitle', Math.random().toString(36).substring(7));
await page.fill('#exampleInputAmount', "120");
await page.click("#invoiceCategory")
await page.fill("#invoiceCategory > input", "Car")
await page.keyboard.press("Enter");
await page.click('button[id="submitInvoiceButton"]');
});
});
This should work as you expected You can also refer to the Dzone Article regarding the same.
Note: Playwright doesn't recommend this approach but this answer should fulfill your need.
Upvotes: 18
Reputation: 2292
Unfortunately, browsers/OSes have global state such as clipboard contents, so you'll get race conditions if testing such features in parallel.
If all your tests are running in parallel, you've probably enabled parallelism in playwright config:
const config: PlaywrightTestConfig = {
fullyParallel: true,
...
This is good - you should leave fullyParallel: true
to execute your tests faster, and then opt-out of running the tests in a single file (or single describe
block) serially by adding test.describe.configure({ mode: 'serial' });
like this:
import { test, expect } from '@playwright/test';
test.describe('Add a simple invoice test', () => {
test.describe.configure({ mode: 'serial' });
test('01.Login & add an invoice', async ({ page }) => {
await page.goto("https://someUrl.com");
await page.fill('input[id="email"]', "someEmailAddress");
await page.fill('input[ng-model="ctrl.user.password"]', "somePassword");
await page.click('button[id="login-btn"]');
});
test('02.Add an invoice', async ({ page }) => {
await page.click('[name="invoice"]');
await page.click('button[id="addInvoiceButton"]');
await page.click('a[ng-click="ctrl.goToAddInvoice()"]');
await page.fill('#invoiceTitle', Math.random().toString(36).substring(7));
await page.fill('#exampleInputAmount', "120");
await page.click("#invoiceCategory")
await page.fill("#invoiceCategory > input", "Car")
await page.keyboard.press("Enter");
await page.click('button[id="submitInvoiceButton"]');
});
});
Read more in the playwright docs here: https://playwright.dev/docs/next/test-parallel#parallelize-tests-in-a-single-file
Upvotes: 15
Reputation: 1
the dzone article referenced in the checked answer uses typescript, but if you don't use typescript here's an example you can use on the playwright docs: https://playwright.dev/docs/test-parallel#serial-mode
Upvotes: -1
Reputation: 516
You can split the file and run it separately too.
import { test, expect } from '@playwright/test';
test('01.Login & add an invoice', async ({ page }) => {
await page.goto("https://someUrl.com");
await page.fill('input[id="email"]', "someEmailAddress");
await page.fill('input[ng-model="ctrl.user.password"]', "somePassword");
await page.click('button[id="login-btn"]');
});
import { test, expect } from '@playwright/test';
test('02.Add an invoice', async ({ page }) => {
await page.click('[name="invoice"]');
await page.click('button[id="addInvoiceButton"]');
await page.click('a[ng-click="ctrl.goToAddInvoice()"]');
await page.fill('#invoiceTitle', Math.random().toString(36).substring(7));
await page.fill('#exampleInputAmount', "120");
await page.click("#invoiceCategory")
await page.fill("#invoiceCategory > input", "Car")
await page.keyboard.press("Enter");
await page.click('button[id="submitInvoiceButton"]');
});
And then run it like:
npx playwright test test1.ts
npx playwright test test2.ts
or depending on your setting it could also be like:
pnpm -C test test1.ts
pnpm -C test test2.ts
Upvotes: -2
Reputation: 532
If you have a bunch of tests that have common setup steps then Playwright Test Runner has some pre-canned features you can use to either run once before all the tests (test.beforeAll) or alternatively before each test (test.beforeEach).
Docs for that are here: https://playwright.dev/docs/test-intro#use-test-hooks
There are similar options for teardown, so they could be something simple like going to the login page and logging in (then logging out at the end?), or something more complex like setting up data and clearing it down after the test.
Upvotes: -1
Reputation: 21597
You shouldn't make your tests depend on each other. For example, I would extract the common login to a function and call that function from both tests. You could even add some asserts to the first test to check that the login worked. But you wouldn't do that on the second one.
Upvotes: 7