| 
									
										
										
										
											2021-12-13 18:30:48 -08:00
										 |  |  | /** | 
					
						
							|  |  |  |  * Copyright (c) Microsoft Corporation. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * 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 * as path from 'path'; | 
					
						
							|  |  |  | import { test as baseTest, Locator } from '@playwright/test'; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | declare global { | 
					
						
							|  |  |  |   interface Window { | 
					
						
							|  |  |  |     __playwright_render: (component: string, props: any) => void; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | type TestFixtures = { | 
					
						
							| 
									
										
										
										
											2021-12-14 19:25:07 -08:00
										 |  |  |   render: (component: { type: string, props: Object }) => Promise<Locator>; | 
					
						
							| 
									
										
										
										
											2021-12-15 19:19:43 -08:00
										 |  |  |   capture: (locator: Locator, name: string) => Promise<void>; | 
					
						
							| 
									
										
										
										
											2021-12-13 18:30:48 -08:00
										 |  |  |   webpack: string; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | export const test = baseTest.extend<TestFixtures>({ | 
					
						
							|  |  |  |   webpack: '', | 
					
						
							| 
									
										
										
										
											2021-12-14 19:25:07 -08:00
										 |  |  |   render: async ({ page, webpack }, use) => { | 
					
						
							| 
									
										
										
										
											2021-12-13 18:30:48 -08:00
										 |  |  |     const webpackConfig = require(webpack); | 
					
						
							|  |  |  |     const outputPath = webpackConfig.output.path; | 
					
						
							|  |  |  |     const filename = webpackConfig.output.filename.replace('[name]', 'playwright'); | 
					
						
							| 
									
										
										
										
											2021-12-14 19:25:07 -08:00
										 |  |  |     await use(async (component: { type: string, props: Object }) => { | 
					
						
							| 
									
										
										
										
											2021-12-13 18:30:48 -08:00
										 |  |  |       await page.route('http://component/index.html', route => { | 
					
						
							|  |  |  |         route.fulfill({ | 
					
						
							|  |  |  |           body: `<html>
 | 
					
						
							|  |  |  |             <meta name='color-scheme' content='dark light'> | 
					
						
							|  |  |  |             <style>html, body { padding: 0; margin: 0; background: #aaa; }</style> | 
					
						
							|  |  |  |             <div id='root' style='width: 100%; height: 100%;'></div> | 
					
						
							|  |  |  |           </html>`,
 | 
					
						
							|  |  |  |           contentType: 'text/html' | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  |       await page.goto('http://component/index.html'); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       await page.addScriptTag({ path: path.resolve(__dirname, outputPath, filename) }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-14 19:25:07 -08:00
										 |  |  |       const props = { ...component.props }; | 
					
						
							|  |  |  |       for (const [key, value] of Object.entries(props)) { | 
					
						
							| 
									
										
										
										
											2021-12-13 18:30:48 -08:00
										 |  |  |         if (typeof value === 'function') { | 
					
						
							|  |  |  |           const functionName = '__pw_func_' + key; | 
					
						
							|  |  |  |           await page.exposeFunction(functionName, value); | 
					
						
							| 
									
										
										
										
											2021-12-14 19:25:07 -08:00
										 |  |  |           (props as any)[key] = functionName; | 
					
						
							| 
									
										
										
										
											2021-12-13 18:30:48 -08:00
										 |  |  |         } | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       await page.evaluate(v => { | 
					
						
							| 
									
										
										
										
											2021-12-14 19:25:07 -08:00
										 |  |  |         const props = v.props; | 
					
						
							|  |  |  |         for (const [key, value] of Object.entries(props)) { | 
					
						
							| 
									
										
										
										
											2021-12-13 18:30:48 -08:00
										 |  |  |           if (typeof value === 'string' && (value as string).startsWith('__pw_func_')) | 
					
						
							| 
									
										
										
										
											2021-12-14 19:25:07 -08:00
										 |  |  |             (props as any)[key] = (window as any)[value]; | 
					
						
							| 
									
										
										
										
											2021-12-13 18:30:48 -08:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2021-12-14 19:25:07 -08:00
										 |  |  |         window.__playwright_render(v.type, props); | 
					
						
							|  |  |  |       }, { type: component.type, props }); | 
					
						
							| 
									
										
										
										
											2021-12-13 18:30:48 -08:00
										 |  |  |       return page.locator('#pw-root'); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  |   }, | 
					
						
							| 
									
										
										
										
											2021-12-15 19:19:43 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   capture: async ({}, use, testInfo) => { | 
					
						
							|  |  |  |     await use(async (locator: Locator, name: string) => { | 
					
						
							|  |  |  |       const screenshotPath = path.join(__dirname, '..', 'screenshots', sanitizeForFilePath(path.basename(testInfo.file) + '-' + testInfo.title + '-' + name) + '.png'); | 
					
						
							|  |  |  |       testInfo.attachments.push({ name, path: screenshotPath, contentType: 'image/png' }); | 
					
						
							|  |  |  |       await locator.screenshot({ path: screenshotPath }); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2021-12-13 18:30:48 -08:00
										 |  |  | }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-15 19:19:43 -08:00
										 |  |  | export function sanitizeForFilePath(s: string) { | 
					
						
							|  |  |  |   return s.replace(/[\x00-\x2C\x2E-\x2F\x3A-\x40\x5B-\x60\x7B-\x7F]+/g, '-'); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-13 18:30:48 -08:00
										 |  |  | export { expect } from '@playwright/test'; |