I'm new to Playwright so please forgive me if I don't use the vernacular correctly.
I have some long end to end test cases to write up that require several different backend webservice connections as well as multiple pages. Is there a more efficient way to pass in all the fixtures? Having to pass in 20+ fixtures to each test is going to be pretty ugly.
test('Smoke Test 1', async ({ loginForm,
detailForm,
listForm,
arrayForm,
addressForm,
confirmationForm,
configForm,
cartForm,
miniCartForm,
emailListForm,
cardForm,
authorizationForm,
bankForm,
routingForm,
webServiceClient1,
webServiceClient2,
webServiceClient3,
webServiceClient4,
webServiceClient5,
webServiceClient6,
webServiceClient7,
page
}) => {
await loginForm.login('jsmith', 'password');
const response = await webServiceClient1.getSomeData();
console.log(`VIN: ${response.data}`);
//use other forms and webservices
});
This is going to get really crazy for each test.
I started looking at my fixture file.
fixtures.ts:
import { test as base } from '@playwright/test';
import { DetailFormControl, HomePageControl, SearchResultsControl } from './page';
import { WebService1Client } from 'data/clients/web-service-one-client';
type MyFixtures = {
detailFormControl: DetailFormControl;
homePageControl: HomePageControl;
webService1Client: WebService1Client;
searchResultsControl: SearchResultsControl;
};
export const test = base.extend<MyFixtures>({
detailFormControl: async ({ page }, use) => {
await use(new detailFormControl(page));
},
homePageControl: async ({ page }, use) => {
await use(new HomePageControl(page));
},
searchResultsControl: async ({ page }, use) => {
await use(new SearchResultsControl(page));
},
webService1Client: async({ }, use) => {
const webService1Client = new WebService1Client(
`http://www.webservice1.com`
);
await use(webService1Client);
}
// about another twenty of these here
});
export { expect, type Page } from '@playwright/test';
And then realized that I could do this - this is called a Composed Fixture:
import { test as base } from '@playwright/test';
import { LoginFormControl, HomePageControl, SearchResultsControl } from '../page';
import { WebServiceClient } from 'data/clients/webservice.client';
type MyFixtures = {
controls: {
loginFormControl: LoginFormControl;
homePageControl: HomePageControl;
searchResultsControl: SearchResultsControl;
};
clients: {
webServiceClient: WebServiceClient;
}
};
export const test = base.extend<MyFixtures>({
controls: async ({ page }, use) => {
const controls = {
loginFormControl: new LoginFormControl(page),
homePageControl: new HomePageControl(page),
searchResultsControl: new SearchResultsControl(page),
};
await use(controls);
},
clients: async ({ }, use) => {
const clients = {
webServiceClient: new WebServiceClient (
`http://www.mywebservice.com`
)
};
await use(clients);
}
});
export { expect, type Page } from '@playwright/test';
Then in my spec files I could do this:
import { test, expect } from '../fixtures/myFixture.ts';
test.describe('Test something', () => {
test('Test Case 1', async ({ controls, clients, page }) => {
await controls.loginFormControl.login('jsmith', 'password');
const response = await clients.webServiceClient.getData();
console.log(`VIN: ${response.data}`);
});
});
I hope this is helpful!