Search code examples
playwright

Is there a more efficient way to pass in all the fixtures?


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.


Solution

  • 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!