UNPKG

@applitools/eyes-storybook

Version:
255 lines (229 loc) 8.15 kB
function __renderStoryWithClientAPI(...args) { var renderStoryWithClientAPI = (function () { 'use strict'; const API_VERSIONS = { v4: 'v4', v5: 'v5', v5_2: 'v5_2', v6_4: 'v6_4', v8: 'v8', }; function getClientAPI() { const frameWindow = getFrameWindow(); const clientAPI = frameWindow.__STORYBOOK_CLIENT_API__; const addons = frameWindow.__STORYBOOK_ADDONS || frameWindow.__STORYBOOK_ADDONS_PREVIEW; return getAPI(getStorybookVersion()); function getStorybookVersion() { const addonsForV4 = frameWindow.__STORYBOOK_ADDONS; if (!clientAPI && frameWindow.__STORYBOOK_PREVIEW__) { return API_VERSIONS.v8; } else if (frameWindow.__STORYBOOK_PREVIEW__) { return API_VERSIONS.v6_4; } else if (frameWindow.__STORYBOOK_STORY_STORE__) { return API_VERSIONS.v5_2; } else if (frameWindow.__STORYBOOK_CLIENT_API__ && frameWindow.__STORYBOOK_CLIENT_API__.raw) { return API_VERSIONS.v5; } else if ( addonsForV4 && addonsForV4.channel && addonsForV4.channel._listeners && addonsForV4.channel._listeners.setCurrentStory && addonsForV4.channel._listeners.setCurrentStory[0] ) { return API_VERSIONS.v4; } else { const storybookVariablesOnWindow = Object.keys(frameWindow).filter(key => key.includes('STORYBOOK'), ); throw new Error( `Cannot get client API: couldn't detect storybook version.${ storybookVariablesOnWindow.length ? ` Found the following storybook variables: ${storybookVariablesOnWindow.join(', ')}` : ' - no STORYBOOK variables found in global scope' }`, ); } } function onStoryRendered(callback) { const channel = addons?.getChannel?.(); if (channel) { channel.once('storyRendered', () => { setTimeout(callback, 0); }); channel.once('playFunctionThrewException', () => { setTimeout(callback, 0); }); channel.once('storyErrored', () => { setTimeout(callback, 0); }); channel.once('storyThrewException', () => { setTimeout(callback, 0); }); } else { callback(); } } function getAPI(version) { if (version) { let api; switch (version) { case API_VERSIONS.v4: { api = { getStories: () => { if (!frameWindow.__APPLITOOLS_STORIES) { frameWindow.__APPLITOOLS_STORIES = Object.values(clientAPI._storyStore._data) .map(({stories, kind}) => Object.values(stories).map(s => ({...s, kind}))) .flat(); } return frameWindow.__APPLITOOLS_STORIES; }, selectStory: i => { const {kind, name: story} = api.getStories()[i]; addons.channel._listeners.setCurrentStory[0]({kind, story}); }, onStoryRendered, }; break; } case API_VERSIONS.v5: { api = { getStories: () => { return clientAPI.raw(); }, selectStory: i => { clientAPI._storyStore.setSelection(clientAPI.raw()[i]); }, onStoryRendered, }; break; } case API_VERSIONS.v5_2: { api = { getStories: () => { return clientAPI.raw(); }, selectStory: i => { frameWindow.__STORYBOOK_STORY_STORE__.setSelection({storyId: clientAPI.raw()[i].id}); }, onStoryRendered, }; break; } case API_VERSIONS.v6_4: { api = { getStories: async () => { if (clientAPI.storyStore.cacheAllCSFFiles) { await clientAPI.storyStore.cacheAllCSFFiles(); } return clientAPI.raw(); }, selectStory: async (i, id) => { let storyId = !clientAPI.storyStore.cacheAllCSFFiles ? clientAPI.raw()[i].id : id; if (!storyId) { await clientAPI.storyStore.cacheAllCSFFiles(); storyId = clientAPI.raw()[i].id; } if (frameWindow.__STORYBOOK_PREVIEW__.urlStore) { frameWindow.__STORYBOOK_PREVIEW__.urlStore.setSelection({ storyId, }); } else { // storybook v7 await clientAPI.storyStore.initializationPromise; frameWindow.__STORYBOOK_PREVIEW__.selectionStore.setSelection({storyId}); } await frameWindow.__STORYBOOK_PREVIEW__.renderSelection(); }, onStoryRendered, }; break; } case API_VERSIONS.v8: { api = { getStories: async () => { await frameWindow.__STORYBOOK_PREVIEW__.ready(); return Object.values(await frameWindow.__STORYBOOK_PREVIEW__.extract()); }, selectStory: async (_i, id) => { await frameWindow.__STORYBOOK_PREVIEW__.ready(); frameWindow.__STORYBOOK_ADDONS_PREVIEW.channel.emit('setCurrentStory', {storyId: id}); }, onStoryRendered, }; } } return {version, ...api}; } } } function getFrameWindow() { if ( (/iframe/.test(window.location.href) && window.__STORYBOOK_PREVIEW__) || /iframe\.html/.test(window.location.href) ) { return window; } const innerFrameWindow = Array.prototype.find.call(window.frames, frame => { try { return ( (/\/iframe/.test(frame.location.href) && frame.__STORYBOOK_PREVIEW__) || /\/iframe\.html/.test(frame.location.href) ); } catch (e) {} }); if (innerFrameWindow) { return innerFrameWindow; } // frame.location.href might not be 'iframe' but still be the correct one if (window.__STORYBOOK_CLIENT_API__ || window.__STORYBOOK_PREVIEW__) { return window; } // the inner frame might have a different url pattern but still be the correct one // this is a fallback in case no other frame matched the usual patterns // and this should be backwards compatible with older storybook versions 🤞 const fallbackFrameWindow = Array.prototype.find.call(window.frames, frame => { try { return frame.__STORYBOOK_PREVIEW__; } catch (e) {} }); if (fallbackFrameWindow) { return fallbackFrameWindow; } throw new Error('Cannot get client API: no frameWindow'); } async function getClientAPIWithRetries({timeout = 5000} = {}) { let error = 'Unknown error'; const RETRY_INTERVAL = 100; const totalAttempts = timeout / RETRY_INTERVAL; for (let attempt = 1; attempt <= totalAttempts; attempt++) { await new Promise(resolve => setTimeout(resolve, RETRY_INTERVAL)); try { return getClientAPI(); } catch (e) { if (!(attempt % 10)) { console.log(`Error in getClientAPI: ${e.message}, attempt ${attempt}/${totalAttempts}`); } error = e; } } throw error; } var getClientAPI_1 = getClientAPIWithRetries; function renderStoryWithClientAPI(index, id) { return new Promise(async resolve => { let api; try { api = await getClientAPI_1(); await api.selectStory(index, id); api.onStoryRendered(resolve); } catch (ex) { resolve({message: ex.message, version: api ? api.version : undefined}); } }); } var renderStoryWithClientAPI_1 = renderStoryWithClientAPI; return renderStoryWithClientAPI_1; }()); return renderStoryWithClientAPI.apply(this, args); } module.exports = __renderStoryWithClientAPI