Skip to content

Commit e1bc3d9

Browse files
authored
feat: Adds Playwright testing. (#24)
* feat: Adds Playwright testing. * feat: Adds Playwright testing. * feat: Adds Playwright testing.
1 parent 3e9dc2c commit e1bc3d9

File tree

15 files changed

+252
-1437
lines changed

15 files changed

+252
-1437
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
# Ignore all node_modules including in subdirectories for samples/
22
**/node_modules/
3+
**/test-results/
34
samples/.env
45

56
# (temporary) Ignore dist files generated by build

e2e/example.spec.ts

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,22 @@
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+
117
import { test, expect } from '@playwright/test';
218
/**
3-
// NOTE: Trying to graft the old js-samples tests in here to see what happens.
19+
// NOTE: KEEP THIS CODE. It contains things you need to add.
420
import { waitForGoogleMapsToLoad, failOnPageError } from "./utils";
521
import fs from "fs";
622

e2e/samples.spec.ts

Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
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+
});

e2e/utils.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,21 @@
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+
// IMPORTANT: Keep this file, it contains things you may need. This file is not
18+
119
import { Page } from "@playwright/test";
220

321
// from https://github.com/lit/lit.dev/blob/5d79d1e0989e68f8b5905e5271229ffe4c55265c/packages/lit-dev-tests/src/playwright/util.ts

package-lock.json

Lines changed: 10 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

playwright.config.ts

Lines changed: 29 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,21 @@
11
import { defineConfig, devices } from '@playwright/test';
22

3+
/*
4+
* Copyright 2024 Google LLC
5+
*
6+
* Licensed under the Apache License, Version 2.0 (the "License");
7+
* you may not use this file except in compliance with the License.
8+
* You may obtain a copy of the License at
9+
*
10+
* https://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing, software
13+
* distributed under the License is distributed on an "AS IS" BASIS,
14+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
* See the License for the specific language governing permissions and
16+
* limitations under the License.
17+
*/
18+
319
/**
420
* Read environment variables from file.
521
* https://github.com/motdotla/dotenv
@@ -20,34 +36,40 @@ export default defineConfig({
2036
/* Retry on CI only */
2137
retries: process.env.CI ? 2 : 0,
2238
/* Opt out of parallel tests on CI. */
23-
workers: process.env.CI ? 1 : undefined,
39+
//workers: process.env.CI ? 1 : undefined,
40+
workers: 1,
2441
/* Reporter to use. See https://playwright.dev/docs/test-reporters */
2542
reporter: 'html',
43+
44+
/* Timeout (tests should complete within 60 seconds) */
45+
//timeout: 60000,
46+
2647
/* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */
2748
use: {
2849
/* Base URL to use in actions like `await page.goto('/')`. */
29-
// baseURL: 'http://127.0.0.1:3000',
50+
baseURL: 'http://localhost:8080',
3051

3152
/* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */
3253
trace: 'on-first-retry',
3354
},
3455

56+
testMatch: 'e2e/samples.spec.ts', // NEW
57+
3558
/* Configure projects for major browsers */
3659
projects: [
3760
{
3861
name: 'chromium',
39-
use: { ...devices['Desktop Chrome'] },
62+
use: { ...devices['Desktop Chrome'], },
4063
},
41-
64+
/**
4265
{
4366
name: 'firefox',
4467
use: { ...devices['Desktop Firefox'] },
4568
},
46-
4769
{
4870
name: 'webkit',
4971
use: { ...devices['Desktop Safari'] },
50-
},
72+
},*/
5173

5274
/* Test against mobile viewports. */
5375
// {
@@ -76,4 +98,4 @@ export default defineConfig({
7698
// url: 'http://127.0.0.1:3000',
7799
// reuseExistingServer: !process.env.CI,
78100
// },
79-
});
101+
});

samples/add-map/index.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
<!--[START maps_add_map]-->
1818
<html>
1919
<head>
20-
<title>Simple Map</title>
20+
<title>Add a Map</title>
2121

2222
<link rel="stylesheet" type="text/css" href="./style.css" />
2323
<script type="module" src="./index.js"></script>

samples/add-map/index.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ async function initMap() {
3434
// [START maps_add_map_instantiate_marker]
3535
// The marker, positioned at Uluru
3636
const marker = new AdvancedMarkerElement({ map, position, title: 'Uluru' });
37-
// [END maps_add_map_instantiate_marker]
37+
// [END maps_add_map_instantiate_marker]
3838
}
3939
initMap();
4040
// [END maps_add_map]

samples/add-map/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ async function initMap(): Promise<void> {
3939
// [START maps_add_map_instantiate_marker]
4040
// The marker, positioned at Uluru
4141
const marker = new AdvancedMarkerElement({map, position, title: 'Uluru'});
42-
// [END maps_add_map_instantiate_marker]
42+
// [END maps_add_map_instantiate_marker]
4343
}
4444
initMap();
4545
// [END maps_add_map]

samples/add-map/package-lock.json

Lines changed: 0 additions & 12 deletions
This file was deleted.

0 commit comments

Comments
 (0)