UNPKG

@applitools/eyes-storybook

Version:
139 lines (120 loc) 5.38 kB
'use strict'; const {storyToCheckSettings} = require('./transformSettings'); const {presult, ptimeoutWithError} = require('@applitools/functional-commons'); const renderStoryWithClientAPI = require('../dist/renderStoryWithClientAPI'); const runRunBeforeScript = require('../dist/runRunBeforeScript'); const getStoryBaselineName = require('./getStoryBaselineName'); const {URL} = require('url'); const runRunAfterScript = require('../dist/runRunAfterScript'); const waitFor = require('./waitFor'); const PAGE_EVALUATE_TIMEOUT = process.env.APPLITOOLS_PAGE_EVALUATE_TIMEOUT || 120000; const DOM_SNAPSHOTS_TIMEOUT = 5 * 60 * 1000; const utils = require('@applitools/utils'); function makeGetStoryData({logger, takeDomSnapshots, reloadPagePerStory, navigationWaitUntil}) { return async function getStoryData({story, storyUrl, page, pageId = 'mock'}) { const title = getStoryBaselineName(story); logger.log(`[page ${pageId}] getting data from story`, title); const eyesParameters = story.parameters && story.parameters.eyes; if (story.isApi && !reloadPagePerStory) { const currentUrl = page.url(); const expectedQueryParams = eyesParameters ? eyesParameters.queryParams : undefined; if (urlQueryParamsEquals(currentUrl, expectedQueryParams)) { try { const err = await ptimeoutWithError( page.evaluate(renderStoryWithClientAPI, story.index, story.id), PAGE_EVALUATE_TIMEOUT, new Error(`[page ${pageId}] page evaluate timed out!`), ); logger.log(`[page ${pageId}] done with page evaluate for story ${title}`); err && handleRenderStoryError(err); } catch (ex) { if (ex.message && !ex.message.includes('Eyes could not render stories properly')) handleRenderStoryError(ex); else { const errMsg = ex.message || ex; throw new Error(errMsg); } } } else { await renderStoryLegacy(); await waitFor(page, 'body.sb-show-main'); } } else { await renderStoryLegacy(); } const wait = story.config.waitBeforeCapture; if (typeof wait === 'number') { utils.guard.isGreaterThenOrEqual(wait, 0, {name: 'waitBeforeCapture'}); } if (eyesParameters && eyesParameters.runBefore) { await page.evaluate(runRunBeforeScript, story.index).catch(err => { logger.log(`[page ${pageId}] error during runBefore: ${err}`); // it might be good to aggregate these errors and output them at the end of the run }); } logger.log(`[page ${pageId}] running takeDomSnapshot(s) for story ${title}`); const domSnapshotsPromise = takeDomSnapshots({ page, ...storyToCheckSettings({story}), waitBeforeCapture: wait ? async () => { logger.log(`[page ${pageId}] waiting before screenshot of ${title} ${wait}`); await waitFor(page, wait); } : undefined, }); const result = await ptimeoutWithError( domSnapshotsPromise, DOM_SNAPSHOTS_TIMEOUT, new Error(`[page ${pageId}] timeout reached when trying to take DOM for story ${title}`), ); logger.log(`[page ${pageId}] done getting DOM for story ${title}`); if (eyesParameters && eyesParameters.runAfter) { await page.evaluate(runRunAfterScript, story.index).catch(err => { logger.log(`[page ${pageId}] error during runAfter: ${err}`); }); } logger.log(`[page ${pageId}] done getting data from story`, title); return result; async function renderStoryLegacy() { logger.log(`[page ${pageId}] getting data from story ${storyUrl}`); const [err] = await presult( page.goto(storyUrl, {timeout: PAGE_EVALUATE_TIMEOUT, waitUntil: navigationWaitUntil}), ); if (err) { logger.log(`[page ${pageId}] error navigating to story ${storyUrl}`, err); throw err; } } function urlQueryParamsEquals(url, expectedQueryParams) { try { url = new URL(url); } catch (err) { logger.error(`[page ${pageId}] Error during parsing page url`, err); return false; } const currentQueryParams = url.searchParams.get('eyes-query-params'); if (!currentQueryParams && !expectedQueryParams) return true; if (!currentQueryParams || !expectedQueryParams) return false; const expectedQueryParamNames = Object.keys(expectedQueryParams); const currentQueryParamNames = currentQueryParams.split(','); if (currentQueryParamNames.length !== expectedQueryParamNames.length) return false; for (const queryParamName of currentQueryParamNames) { if (url.searchParams.get(queryParamName) !== expectedQueryParams[queryParamName]) { return false; } } return true; } // TODO (amit): handle this error in the caller (probably renderStories) function handleRenderStoryError(error) { logger.log(`[page ${pageId}] ${error.message}`); const versionMsg = error.version ? ` The detected version of storybook is ${error.version}.` : ''; throw new Error( `Eyes could not render stories properly.${versionMsg} Contact support@applitools.com for troubleshooting. Original error: ${error.message}`, ); } }; } module.exports = makeGetStoryData;