Skip to content

Commit e722471

Browse files
authored
Merge pull request #238 from orionrobots/copilot/fix-237
Implement Playwright step definitions for BDD staging tests
2 parents 1b6a944 + feda356 commit e722471

File tree

4 files changed

+134
-14
lines changed

4 files changed

+134
-14
lines changed

Dockerfile

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,20 @@ COPY . /usr/local/apache2/htdocs/
4747

4848
FROM base AS tests
4949

50+
# Install necessary packages for Playwright
51+
RUN apt-get update && apt-get install -y \
52+
libnss3 \
53+
libatk-bridge2.0-0 \
54+
libdrm2 \
55+
libxkbcommon0 \
56+
libgtk-3-0 \
57+
libgbm1 \
58+
libasound2 \
59+
&& rm -rf /var/lib/apt/lists/*
60+
61+
# Install Playwright browsers
62+
RUN npx playwright install chromium --with-deps
63+
5064
# Set default command to run BDD tests
5165
CMD ["npm", "run", "test:bdd"]
5266

package-lock.json

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

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@
4444
"markdown-it-attrs": "^4.3.1",
4545
"mini-css-extract-plugin": "^2.9.1",
4646
"moment": "^2.30.1",
47+
"playwright": "^1.54.2",
4748
"postcss-loader": "^8.1.1",
4849
"sass": "^1.89.1",
4950
"sass-loader": "^16.0.2",
Lines changed: 71 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,78 @@
1-
// Basic step definitions for BDD tests
2-
// These are intentionally minimal placeholders to demonstrate the test framework setup
1+
// Basic step definitions for BDD tests using Playwright
2+
const { Given, When, Then, BeforeAll, AfterAll } = require('@cucumber/cucumber');
3+
const { chromium } = require('playwright');
34

4-
const { Given, When, Then } = require('@cucumber/cucumber');
5+
let browser;
6+
let context;
7+
let page;
58

6-
// This step definition is intentionally empty to show the framework works
7-
// but tests still fail due to missing implementation
8-
Given('the Staging site is started', function () {
9-
// TODO: Implement step to start/verify staging site
10-
return 'pending';
9+
// Set up BASE_URL with default value for staging service in Docker network
10+
const BASE_URL = process.env.BASE_URL || 'http://staging';
11+
12+
BeforeAll(async function () {
13+
browser = await chromium.launch({
14+
headless: true,
15+
args: ['--no-sandbox', '--disable-setuid-sandbox']
16+
});
17+
context = await browser.newContext({
18+
// Increase timeout for slower Docker environments
19+
timeout: 30000
20+
});
21+
});
22+
23+
AfterAll(async function () {
24+
if (context) await context.close();
25+
if (browser) await browser.close();
26+
});
27+
28+
Given('the Staging site is started', async function () {
29+
page = await context.newPage();
30+
31+
try {
32+
// Verify that the BASE_URL can be reached (allow redirects)
33+
const response = await page.goto(BASE_URL, {
34+
waitUntil: 'networkidle',
35+
timeout: 30000
36+
});
37+
38+
if (!response || !response.ok()) {
39+
throw new Error(`Failed to reach staging site at ${BASE_URL}. Status: ${response ? response.status() : 'No response'}`);
40+
}
41+
} catch (error) {
42+
throw new Error(`Unable to connect to staging site at ${BASE_URL}: ${error.message}`);
43+
}
1144
});
1245

13-
When('the index page is visited', function () {
14-
// TODO: Implement step to visit index page
15-
return 'pending';
46+
When('the index page is visited', async function () {
47+
if (!page) {
48+
throw new Error('Page not initialized. Make sure "Given the Staging site is started" step is executed first.');
49+
}
50+
51+
// Navigate to the index page and ensure it loads without HTTP errors
52+
const response = await page.goto(BASE_URL, {
53+
waitUntil: 'networkidle',
54+
timeout: 30000
55+
});
56+
57+
if (!response || !response.ok()) {
58+
throw new Error(`Index page failed to load. Status: ${response ? response.status() : 'No response'}`);
59+
}
60+
61+
// Verify the page has loaded by checking for basic HTML structure
62+
await page.waitForSelector('html', { timeout: 10000 });
1663
});
1764

18-
Then('the Logo should be displayed in the top left corner', function () {
19-
// TODO: Implement step to verify logo presence and position
20-
return 'pending';
65+
Then('the Logo should be displayed in the top left corner', async function () {
66+
if (!page) {
67+
throw new Error('Page not initialized. Make sure previous steps are executed first.');
68+
}
69+
70+
// Check that favicon.png is somewhere nested under a <nav> element
71+
// This covers both relative paths (favicon.png) and absolute URLs containing favicon.png
72+
try {
73+
const faviconInNav = await page.locator('nav img[src*="favicon.png"]').first();
74+
await faviconInNav.waitFor({ state: 'visible', timeout: 10000 });
75+
} catch (error) {
76+
throw new Error('Logo (favicon.png) is not displayed in a nav element');
77+
}
2178
});

0 commit comments

Comments
 (0)