1+ /*
2+ * Copyright 2025 Google LLC
3+ *
4+ * Licensed under the Apache License, Version 2.0 (the "License");
5+ * you may not use this file except in compliance with the License.
6+ * You may obtain a copy of the License at
7+ *
8+ * https://www.apache.org/licenses/LICENSE-2.0
9+ *
10+ * Unless required by applicable law or agreed to in writing, software
11+ * distributed under the License is distributed on an "AS IS" BASIS,
12+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+ * See the License for the specific language governing permissions and
14+ * limitations under the License.
15+ */
16+
17+ import { test , expect } from '@playwright/test' ;
18+ import fs from 'fs' ;
19+ import path from 'path' ;
20+ import childProcess from 'child_process' ;
21+
22+ const samplesDir = path . join ( __dirname , '..' , 'samples' ) ;
23+
24+ const sampleFolders = fs . readdirSync ( samplesDir ) . filter ( ( file ) => {
25+ return fs . statSync ( path . join ( samplesDir , file ) ) . isDirectory ( ) ;
26+ } ) ;
27+
28+ // Iterate through samples and run the same test for each one.
29+ sampleFolders . forEach ( ( sampleFolder ) => {
30+ test ( `test ${ sampleFolder } ` , async ( { page } ) => {
31+
32+ // START Build the sample
33+ const buildProcess = childProcess . spawn ( 'npm' , [ 'run' , 'build' ] , {
34+ cwd : path . join ( samplesDir , sampleFolder ) ,
35+ stdio : 'inherit' ,
36+ } ) ;
37+
38+ await new Promise ( ( resolve , reject ) => {
39+ buildProcess . on ( 'close' , ( code ) => {
40+ if ( code === 0 ) {
41+ resolve ( true ) ;
42+ } else {
43+ reject ( `Build process exited with code ${ code } ` ) ;
44+ }
45+ } ) ;
46+ } ) ;
47+ // END Build the sample
48+
49+ // START run the preview
50+ // Get an available port
51+ const port = 8080 ;
52+
53+ const url = `http://localhost:${ port } /` ;
54+
55+ const viteProcess = childProcess . spawn ( 'vite' , [ 'preview' , `--port=${ port } ` ] , {
56+ cwd : path . join ( samplesDir , sampleFolder ) ,
57+ stdio : 'inherit' ,
58+ } ) ;
59+
60+ await new Promise ( ( resolve ) => setTimeout ( resolve , 500 ) ) ; // Set a timeout to let the web server start.
61+ // END run the preview
62+
63+ /**
64+ * Run all of the tests. Each method call either runs a test or inserts a timeout for loading.
65+ * `expect`s are assertions that test for conditions.
66+ * Run `npx playwright test --ui` to launch Playwright in UI mode to iteratively debug this file.
67+ */
68+ try {
69+ // Check for console errors. Define a promise, then call after page load.
70+ const consoleErrors : string [ ] = [ ] ;
71+ const errorPromise = new Promise < void > ( ( resolve ) => {
72+ page . on ( 'console' , ( msg => {
73+ if ( msg . type ( ) === 'error' ) {
74+ consoleErrors . push ( msg . text ( ) ) ;
75+ resolve ( ) ;
76+ }
77+ } ) ) ;
78+
79+ page . on ( 'pageerror' , ( exception ) => {
80+ consoleErrors . push ( exception . message ) ;
81+ resolve ( ) ;
82+ } ) ;
83+
84+ // Set a timeout to resolve the promise even if no error occurs.
85+ setTimeout ( ( ) => {
86+ resolve ( ) ;
87+ } , 500 ) ;
88+ } ) ;
89+
90+ // Navigate to the page.
91+ await page . goto ( url ) ;
92+
93+ // There must be no console errors.
94+ await errorPromise ;
95+ expect ( consoleErrors ) . toHaveLength ( 0 ) ;
96+
97+ // Wait for the page DOM to load; this does NOT include the Google Maps APIs.
98+ await page . waitForLoadState ( 'domcontentloaded' ) ;
99+
100+ // Wait for Google Maps to load.
101+ await page . waitForFunction ( ( ) => window . google && window . google . maps ) ;
102+
103+ // Insert a delay in ms to let the map load.
104+ await new Promise ( ( resolve ) => setTimeout ( resolve , 1000 ) ) ;
105+
106+ // Yo dawg, I heard you like tests, so I made you a test for testing your tests.
107+ //await expect(page).toHaveTitle('Simple Map'); // Passes on the simple map page, fails on the other as expected.
108+
109+ // Assertions. These must be met or the test will fail.
110+ // The sample must load the Google Maps API.
111+ const hasGoogleMaps = await page . evaluate ( ( ) => {
112+ return typeof window . google !== 'undefined' && typeof window . google . maps !== 'undefined' ;
113+ } ) ;
114+
115+ await expect ( hasGoogleMaps ) . toBeTruthy ( ) ;
116+
117+ const mapElement = await page . locator ( '#map' ) ;
118+ if ( await page . locator ( '#map' ) . isVisible ( ) ) {
119+ console . log ( `✅ Assertion passed: Map is visible.` ) ;
120+ } else {
121+ console . error ( `❌ Assertion failed: Map is not visible.` ) ;
122+ throw new Error ( 'Assertion failed: Map is not visible.' ) ;
123+ }
124+ } finally {
125+ viteProcess . kill ( ) ;
126+ }
127+ } ) ;
128+ } ) ;
0 commit comments