剧作家之前的所有规格文件

Playwright before each for all spec files

我对 Playwright 很陌生。由于我的测试套件,我需要在每次测试 运行 之前登录我的应用程序。在一个简单的 spec 文件中,我可以简单地调用 test.beforeEach。我的问题是:我需要在每次测试每个规范文件之前登录。

test.describe('Test', () => {
    //I need to make the code inside this beforeEach a exported 
    //function to call inside the before each of every spec file I have
    test.beforeEach(async ({ page }) => {
        await page.goto('/login');
        await page.click('text=Log in with Google account');
        await page.fill('id=identifierId', LoginAutomationCredentials.USER);
        await page.click('button[jsname="LgbsSe"]');
        await page.fill('input[type="password"]', LoginAutomationCredentials.PASSWORD);
        await page.click('button[jsname="LgbsSe"]');
        const otp = authenticator.generateToken(LoginAutomationCredentials.TOKEN);
        await page.fill('id=totpPin', otp);
        await page.click('button[jsname="LgbsSe"]');
    });

    it('Some description', async ({ page }) => {
        await page.goto('/foo');
        const dateFilter = await page.inputValue('input[placeholder="2011/03/02"]');
        expect(dateFilter).toBe('2021/12/07');
    });
});

我尝试简单地获取该代码并将其作为一个单独的 .ts 文件中的函数,然后将其导入,但我认为需要上下文才能执行此操作。这可能是每个使用剧作家的测试人员都知道并经常使用的东西,但是,我没有找到任何关于这个主题的东西。

如何避免复制 beforeEach 的整个代码并将其粘贴到我所有的规范文件中?我怎样才能使它成为一个函数并在需要时调用它?

使用灯具。

fixture.js:

const base = require('@playwright/test')
const newTest = base.test.extend({
    login: async({page}, use) => {
        await login();
        await use(page); //runs test here
        //logic after test
    }
})
exports.newTest = newTest
exports.expect = newTest.expect

然后在你的测试中:

const {newTest} = require('fixture.js')
newTest('mytest', async ({login}) => {
    //test logic
    login.goto(''); // using login here since I pass it as page in the fixture.
})

Fixtures 是正确的方法,但是有一个更好的选择,而不是在您要登录时必须记住使用 login 而不是 page。我就是这样做的...

首先,我在 playwright/src/index.ts 中设置了我的项目的所有固定装置:

import { test as base_test, expect } from 'playwright_test';

type TestFixtures = {
  user: string;
};

export const test = base_test.extend<TestFixtures>( {
  user : 'default-user@example.com',
  async context( { user, context, request }, use ) {
    // This makes a REST request to the backend to get a JWT token
    // and then stores that token in the browsers localStorage,
    // but you could replace this with whatever makes sense for auth
    // in your app
    if ( user ) {
      const content = await getAuthScript( user, request );
      await context.addInitScript( { content } );
    }
    await use( context );
  },
} );

/**
 * This makes a REST request to the backend to get a JWT token
 * and then stores that token in the browsers localStorage,
 * but you could replace this with whatever makes sense for auth
 * in your app.
 */
async function getAuthScript( user, request ) {
  const res = await request.post( '/api/test/auth', { data : { user } } );
  const { token } = await res.json();
  return `window.localStorage.setItem( 'jwt-token', "${token}" );`;
}

export { test, expect }

我还要确保 playwright/tsconfig.json 包含以下内容:

{
  "extends": "../path/to/base/tsconfig.json",
  "compilerOptions": {
    "noEmit": true,
    "paths": {
      "~": [ "./src" ],
      "~*": [ "./src/*" ]
    },
    "baseUrl": ".",
    "rootUrl": ".",
  },
  "include": [
    "src/**/*.ts",
    "test/**/*.ts"
  ],
}

现在每个测试都会自动以 default-user@example.com 登录,但是如果您需要一个测试以不同的用户身份登录,您需要在该测试文件中做的就是:

import { test, expect } from '~';

test.use( { user : 'somebody-else@example.com' } );
test( 'can login as somebody-else', async ( { page } ) => {
  // Run your tests here...
} );