mirror of
				https://github.com/microsoft/playwright.git
				synced 2025-06-26 21:40:17 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			275 lines
		
	
	
		
			9.0 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
			
		
		
	
	
			275 lines
		
	
	
		
			9.0 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
/**
 | 
						|
 * Copyright Microsoft Corporation. All rights reserved.
 | 
						|
 *
 | 
						|
 * Licensed under the Apache License, Version 2.0 (the "License");
 | 
						|
 * you may not use this file except in compliance with the License.
 | 
						|
 * You may obtain a copy of the License at
 | 
						|
 *
 | 
						|
 *     http://www.apache.org/licenses/LICENSE-2.0
 | 
						|
 *
 | 
						|
 * Unless required by applicable law or agreed to in writing, software
 | 
						|
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
						|
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
						|
 * See the License for the specific language governing permissions and
 | 
						|
 * limitations under the License.
 | 
						|
 */
 | 
						|
 | 
						|
import { test, expect } from './playwright-test-fixtures';
 | 
						|
 | 
						|
for (const mode of ['legacy', 'default']) {
 | 
						|
  test.describe(`${mode} mode`, () => {
 | 
						|
    const env = { PW_TEST_LEGACY_GLOBAL_SETUP_MODE: mode === 'legacy' ? '1' : undefined };
 | 
						|
 | 
						|
    test('globalSetup and globalTeardown should work', async ({ runInlineTest }) => {
 | 
						|
      const { results, output } = await runInlineTest({
 | 
						|
        'playwright.config.ts': `
 | 
						|
          import * as path from 'path';
 | 
						|
          module.exports = {
 | 
						|
            globalSetup: './globalSetup',
 | 
						|
            globalTeardown: path.join(__dirname, 'globalTeardown.ts'),
 | 
						|
          };
 | 
						|
        `,
 | 
						|
        'globalSetup.ts': `
 | 
						|
          module.exports = async () => {
 | 
						|
            await new Promise(f => setTimeout(f, 100));
 | 
						|
            global.value = 42;
 | 
						|
            process.env.FOO = String(global.value);
 | 
						|
          };
 | 
						|
        `,
 | 
						|
        'globalTeardown.ts': `
 | 
						|
          module.exports = async () => {
 | 
						|
            console.log('teardown=' + global.value);
 | 
						|
          };
 | 
						|
        `,
 | 
						|
        'a.test.js': `
 | 
						|
          const { test } = pwt;
 | 
						|
          test('should work', async ({}, testInfo) => {
 | 
						|
            expect(process.env.FOO).toBe('42');
 | 
						|
          });
 | 
						|
        `,
 | 
						|
      }, undefined, env);
 | 
						|
      expect(results[0].status).toBe('passed');
 | 
						|
      expect(output).toContain('teardown=42');
 | 
						|
    });
 | 
						|
 | 
						|
    test('globalTeardown runs after failures', async ({ runInlineTest }) => {
 | 
						|
      const { results, output } = await runInlineTest({
 | 
						|
        'playwright.config.ts': `
 | 
						|
          import * as path from 'path';
 | 
						|
          module.exports = {
 | 
						|
            globalSetup: 'globalSetup.ts',
 | 
						|
            globalTeardown: './globalTeardown.ts',
 | 
						|
          };
 | 
						|
        `,
 | 
						|
        'globalSetup.ts': `
 | 
						|
          module.exports = async () => {
 | 
						|
            await new Promise(f => setTimeout(f, 100));
 | 
						|
            global.value = 42;
 | 
						|
            process.env.FOO = String(global.value);
 | 
						|
          };
 | 
						|
        `,
 | 
						|
        'globalTeardown.ts': `
 | 
						|
          module.exports = async () => {
 | 
						|
            console.log('teardown=' + global.value);
 | 
						|
          };
 | 
						|
        `,
 | 
						|
        'a.test.js': `
 | 
						|
          const { test } = pwt;
 | 
						|
          test('should work', async ({}, testInfo) => {
 | 
						|
            expect(process.env.FOO).toBe('43');
 | 
						|
          });
 | 
						|
        `,
 | 
						|
      }, undefined, env);
 | 
						|
      expect(results[0].status).toBe('failed');
 | 
						|
      expect(output).toContain('teardown=42');
 | 
						|
    });
 | 
						|
 | 
						|
    test('globalTeardown does not run when globalSetup times out', async ({ runInlineTest }) => {
 | 
						|
      test.skip(!!env.PW_TEST_LEGACY_GLOBAL_SETUP_MODE);
 | 
						|
      const result = await runInlineTest({
 | 
						|
        'playwright.config.ts': `
 | 
						|
          import * as path from 'path';
 | 
						|
          module.exports = {
 | 
						|
            globalSetup: './globalSetup.ts',
 | 
						|
            globalTeardown: 'globalTeardown.ts',
 | 
						|
            globalTimeout: 1000,
 | 
						|
          };
 | 
						|
        `,
 | 
						|
        'globalSetup.ts': `
 | 
						|
          module.exports = async () => {
 | 
						|
            await new Promise(f => setTimeout(f, 10000));
 | 
						|
          };
 | 
						|
        `,
 | 
						|
        'globalTeardown.ts': `
 | 
						|
          module.exports = async () => {
 | 
						|
            console.log('teardown=');
 | 
						|
          };
 | 
						|
        `,
 | 
						|
        'a.test.js': `
 | 
						|
          const { test } = pwt;
 | 
						|
          test('should not run', async ({}, testInfo) => {
 | 
						|
          });
 | 
						|
        `,
 | 
						|
      }, undefined, env);
 | 
						|
      // We did not run tests, so we should only have 1 skipped test.
 | 
						|
      expect(result.skipped).toBe(1);
 | 
						|
      expect(result.passed).toBe(0);
 | 
						|
      expect(result.failed).toBe(0);
 | 
						|
      expect(result.exitCode).toBe(1);
 | 
						|
      expect(result.output).not.toContain('teardown=');
 | 
						|
    });
 | 
						|
 | 
						|
    test('globalSetup should work with sync function', async ({ runInlineTest }) => {
 | 
						|
      const { passed } = await runInlineTest({
 | 
						|
        'playwright.config.ts': `
 | 
						|
          import * as path from 'path';
 | 
						|
          module.exports = {
 | 
						|
            globalSetup: './globalSetup.ts',
 | 
						|
          };
 | 
						|
        `,
 | 
						|
        'globalSetup.ts': `
 | 
						|
          module.exports = () => {
 | 
						|
            process.env.FOO = JSON.stringify({ foo: 'bar' });
 | 
						|
          };
 | 
						|
        `,
 | 
						|
        'a.test.js': `
 | 
						|
          const { test } = pwt;
 | 
						|
          test('should work', async ({}) => {
 | 
						|
            const value = JSON.parse(process.env.FOO);
 | 
						|
            expect(value).toEqual({ foo: 'bar' });
 | 
						|
          });
 | 
						|
        `,
 | 
						|
      }, undefined, env);
 | 
						|
      expect(passed).toBe(1);
 | 
						|
    });
 | 
						|
 | 
						|
    test('globalSetup should throw when passed non-function', async ({ runInlineTest }) => {
 | 
						|
      const { output } = await runInlineTest({
 | 
						|
        'playwright.config.ts': `
 | 
						|
          import * as path from 'path';
 | 
						|
          module.exports = {
 | 
						|
            globalSetup: './globalSetup.ts',
 | 
						|
          };
 | 
						|
        `,
 | 
						|
        'globalSetup.ts': `
 | 
						|
          module.exports = 42;
 | 
						|
        `,
 | 
						|
        'a.test.js': `
 | 
						|
          const { test } = pwt;
 | 
						|
          test('should work', async ({}) => {
 | 
						|
          });
 | 
						|
        `,
 | 
						|
      }, undefined, env);
 | 
						|
      expect(output).toContain(`globalSetup.ts: globalSetup file must export a single function.`);
 | 
						|
    });
 | 
						|
 | 
						|
    test('globalSetup should work with default export and run the returned fn', async ({ runInlineTest }) => {
 | 
						|
      const { output, exitCode, passed } = await runInlineTest({
 | 
						|
        'playwright.config.ts': `
 | 
						|
          import * as path from 'path';
 | 
						|
          module.exports = {
 | 
						|
            globalSetup: './globalSetup.ts',
 | 
						|
          };
 | 
						|
        `,
 | 
						|
        'globalSetup.ts': `
 | 
						|
          function setup() {
 | 
						|
            let x = 42;
 | 
						|
            console.log('\\n%%setup: ' + x);
 | 
						|
            return async () => {
 | 
						|
              await x;
 | 
						|
              console.log('\\n%%teardown: ' + x);
 | 
						|
            };
 | 
						|
          }
 | 
						|
          export default setup;
 | 
						|
        `,
 | 
						|
        'a.test.js': `
 | 
						|
          const { test } = pwt;
 | 
						|
          test('should work', async ({}) => {
 | 
						|
          });
 | 
						|
        `,
 | 
						|
      }, undefined, env);
 | 
						|
      expect(passed).toBe(1);
 | 
						|
      expect(exitCode).toBe(0);
 | 
						|
      expect(output).toContain(`%%setup: 42`);
 | 
						|
      expect(output).toContain(`%%teardown: 42`);
 | 
						|
    });
 | 
						|
 | 
						|
    test('globalSetup should allow requiring a package from node_modules', async ({ runInlineTest }) => {
 | 
						|
      const { results } = await runInlineTest({
 | 
						|
        'playwright.config.ts': `
 | 
						|
          import * as path from 'path';
 | 
						|
          module.exports = {
 | 
						|
            globalSetup: 'my-global-setup'
 | 
						|
          };
 | 
						|
        `,
 | 
						|
        'node_modules/my-global-setup/index.js': `
 | 
						|
          module.exports = async () => {
 | 
						|
            await new Promise(f => setTimeout(f, 100));
 | 
						|
            global.value = 42;
 | 
						|
            process.env.FOO = String(global.value);
 | 
						|
          };
 | 
						|
        `,
 | 
						|
        'a.test.js': `
 | 
						|
          const { test } = pwt;
 | 
						|
          test('should work', async ({}, testInfo) => {
 | 
						|
            expect(process.env.FOO).toBe('42');
 | 
						|
          });
 | 
						|
        `,
 | 
						|
      }, undefined, env);
 | 
						|
      expect(results[0].status).toBe('passed');
 | 
						|
    });
 | 
						|
 | 
						|
    const authFiles = {
 | 
						|
      'playwright.config.ts': `
 | 
						|
        const config: pwt.PlaywrightTestConfig = {
 | 
						|
          globalSetup: require.resolve('./auth'),
 | 
						|
          use: {
 | 
						|
            baseURL: 'https://www.example.com',
 | 
						|
            storageState: 'state.json',
 | 
						|
          },
 | 
						|
        };
 | 
						|
        export default config;
 | 
						|
      `,
 | 
						|
      'auth.ts': `
 | 
						|
        async function globalSetup(config: pwt.FullConfig) {
 | 
						|
          const { baseURL, storageState } = config.projects[0].use;
 | 
						|
          const browser = await pwt.chromium.launch();
 | 
						|
          const page = await browser.newPage();
 | 
						|
          await page.route('**/*', route => {
 | 
						|
            route.fulfill({ body: '<html></html>' }).catch(() => {});
 | 
						|
          });
 | 
						|
          await page.goto(baseURL!);
 | 
						|
          await page.evaluate(() => {
 | 
						|
            localStorage['name'] = 'value';
 | 
						|
          });
 | 
						|
          await page.context().storageState({ path: storageState as string });
 | 
						|
          await browser.close();
 | 
						|
        };
 | 
						|
        export default globalSetup;
 | 
						|
      `,
 | 
						|
      'a.test.ts': `
 | 
						|
        const { test } = pwt;
 | 
						|
        test('should have storage state', async ({ page }) => {
 | 
						|
          await page.route('**/*', route => {
 | 
						|
            route.fulfill({ body: '<html></html>' }).catch(() => {});
 | 
						|
          });
 | 
						|
          await page.goto('/');
 | 
						|
          const value = await page.evaluate(() => localStorage['name']);
 | 
						|
          expect(value).toBe('value');
 | 
						|
        });
 | 
						|
      `,
 | 
						|
    };
 | 
						|
 | 
						|
    test('globalSetup should work for auth', async ({ runInlineTest }) => {
 | 
						|
      const result = await runInlineTest(authFiles, undefined, env);
 | 
						|
      expect(result.exitCode).toBe(0);
 | 
						|
      expect(result.passed).toBe(1);
 | 
						|
    });
 | 
						|
 | 
						|
    test('globalSetup auth should compile', async ({ runTSC }) => {
 | 
						|
      const result = await runTSC(authFiles);
 | 
						|
      expect(result.exitCode).toBe(0);
 | 
						|
    });
 | 
						|
  });
 | 
						|
}
 |