1 | import { logger } from '@storybook/node-logger';
|
2 | import { constructUrl } from './url';
|
3 | import { defaultPuppeteerTestConfig } from './config';
|
4 | export const puppeteerTest = (customConfig = {}) => {
|
5 | const { storybookUrl, chromeExecutablePath, getGotoOptions, customizePage, getCustomBrowser, browserLaunchOptions, testBody, setupTimeout, testTimeout, } = { ...defaultPuppeteerTestConfig, ...customConfig };
|
6 | let browser;
|
7 | let page;
|
8 | const testFn = async ({ context }) => {
|
9 | const { kind, framework, name, id } = context;
|
10 | if (framework === 'react-native') {
|
11 |
|
12 | logger.error("It seems you are running puppeteer test on RN app and it's not supported. Skipping test.");
|
13 | return;
|
14 | }
|
15 | const url = constructUrl(storybookUrl, id);
|
16 | const options = { context, url };
|
17 | if (testBody.filter != null && !testBody.filter(options)) {
|
18 | return;
|
19 | }
|
20 | if (!browser || !page) {
|
21 | logger.error(`Error when running puppeteer test for ${kind} - ${name} : It seems the headless browser is not running.`);
|
22 | throw new Error('no-headless-browser-running');
|
23 | }
|
24 | try {
|
25 | await customizePage(page);
|
26 | await page.goto(url, getGotoOptions(options));
|
27 | }
|
28 | catch (e) {
|
29 | logger.error(`Error when connecting to ${url}, did you start or build the storybook first? A storybook instance should be running or a static version should be built when using puppeteer test feature.`);
|
30 | throw e;
|
31 | }
|
32 | await testBody(page, options);
|
33 | };
|
34 | testFn.timeout = testTimeout;
|
35 | const cleanup = async () => {
|
36 | if (getCustomBrowser && page) {
|
37 | await page.close();
|
38 | }
|
39 | else if (browser) {
|
40 | await browser.close();
|
41 | }
|
42 | };
|
43 | process.on('SIGINT', async () => {
|
44 | await cleanup();
|
45 | process.exit();
|
46 | });
|
47 | testFn.afterAll = cleanup;
|
48 | const beforeAll = async () => {
|
49 | if (getCustomBrowser) {
|
50 | browser = await getCustomBrowser();
|
51 | }
|
52 | else {
|
53 |
|
54 | const puppeteer = require('puppeteer');
|
55 |
|
56 | browser = await puppeteer.launch({
|
57 | ...browserLaunchOptions,
|
58 | args: [
|
59 | '--no-sandbox ',
|
60 | '--disable-setuid-sandbox',
|
61 | '--disable-dev-shm-usage',
|
62 | ...(browserLaunchOptions?.args || []),
|
63 | ],
|
64 | executablePath: chromeExecutablePath,
|
65 | });
|
66 | }
|
67 | page = await browser.newPage();
|
68 | };
|
69 | beforeAll.timeout = setupTimeout;
|
70 | testFn.beforeAll = beforeAll;
|
71 | return testFn;
|
72 | };
|