Skip to content

Add new UI smoke tests #300

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: mainframe
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 7 additions & 11 deletions .github/workflows/playwright.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: Testing for visual regression on old theme
name: Running Playwright test on UI

# Run the workflow when code is pushed or when a pull request is created
on:
Expand All @@ -25,19 +25,16 @@ jobs:
- name: Install dependencies and playwright browsers
run: cd tests && npm ci && npx playwright install --with-deps
- name: Run Playwright tests
id: test-visual
id: test-ui
run: |
make tests | tee output.log
if grep -q -e "Error: A snapshot doesn't exist at" -e "Screenshot comparison failed" output.log; then
echo "Playwright tests failed due to a snapshot issue."
exit 1
elif grep -q "failed" output.log; then
echo "Playwright tests failed due to a non-snapshot issue."
if grep -q "failed" output.log; then
echo "Playwright tests failed. Please view the Playwright report to see full error."
exit 1
fi
- uses: actions/upload-artifact@v4
id: artifact-upload
if: ${{ !cancelled() && failure() && steps.test-visual.conclusion == 'failure' }}
if: ${{ !cancelled() && failure() && steps.test-ui.conclusion == 'failure' }}
with:
name: playwright-report
path: tests/playwright-report/
Expand All @@ -47,10 +44,9 @@ jobs:
if: ${{ failure() }}
with:
script: |
const body = `### <span aria-hidden="true">❌</span> Playwright visual snapshot differences were detected.
const body = `### <span aria-hidden="true">❌</span> Playwright differences were detected.

View the [Playwright report](${{ steps.artifact-upload.outputs.artifact-url }})
**To approve the snapshot changes and update the snapshots, please comment:** /approve-snapshots`;
View the [Playwright report](${{ steps.artifact-upload.outputs.artifact-url }})`;

await github.rest.issues.createComment({
issue_number: context.issue.number,
Expand Down
58 changes: 0 additions & 58 deletions .github/workflows/update-screenshot.yml

This file was deleted.

4 changes: 2 additions & 2 deletions layouts/404.html
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{{ define "main"}}

<div class="content">
<div class="not-found-container">
<div class="content" data-testid="content">
<div class="not-found-container" data-testid="not-found-container">
<h1 class="info-header">
HTTP 404 - Page not found
</h1>
Expand Down
6 changes: 3 additions & 3 deletions layouts/_default/baseof.html
Original file line number Diff line number Diff line change
Expand Up @@ -43,17 +43,17 @@
{{ end }}
<input type="checkbox" id="sidebar-panel" class="sidebar-panel" hidden/>
<div class="grid-container">
<aside class="sidebar">
<aside class="sidebar" data-testid="sidebar">
{{ partial "sidebar-v2.html" . }}
</aside>

<header class="header">
<header class="header" data-testid="header">
{{ block "header" . }}{{end}}
</header>

{{ block "main" . }}{{ end }}

<footer class="footer">
<footer class="footer" data-testid="footer">
{{ block "footer-v2" . }}
{{ partial "footer-v2.html" . }}
{{ end }}
Expand Down
2 changes: 1 addition & 1 deletion layouts/_default/list.html
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{{ define "main" }}

<main class="content " role="main">
<main class="content " role="main" data-testid="content">
<section class="main-layout">
<section id="maincontent" class="content-layout">
<div data-cms-edit="content" class="text-content list-page">
Expand Down
2 changes: 1 addition & 1 deletion layouts/_default/single.html
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{{ define "main" }}

<main class="content">
<main class="content" data-testid="content">
<!-- Replace icons -->
{{ $content := partial "icon-replacement.html" (dict "content" .Content) }}

Expand Down
2 changes: 1 addition & 1 deletion layouts/partials/api.html
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<!--Use wide page layout for the API reference pages-->
<div class="nginx-docs-api-container">
<div id="api-component" class="content">
<div id="api-component" class="content" data-testid="content">
{{ .Content}}
</div>
</div>
Expand Down
4 changes: 2 additions & 2 deletions layouts/partials/footer-v2.html
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
<div class="footer-layout">
<div class="footer-f5-trademark">
<div class="footer-f5-trademark" data-testid="footer-f5-trademark">
<img class="f5-logo-footer" src="{{ "/images/icons/Logo_F5.svg" | absURL }}" alt="F5 logo">
<p>©2025 F5, Inc. All rights reserved. NGINX is a registered trademark of F5, Inc.</p>
</div>
<div class="footer-useful-links">
<div class="footer-useful-links" data-testid="footer-useful-links">
<a
href="https://www.f5.com/company/policies/trademarks"
rel="noopener"
Expand Down
16 changes: 8 additions & 8 deletions layouts/partials/header.html
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
</a>
</div>

<div class="header__product-selector">
<div class="header__product-selector" data-testid="header__product-selector">
{{ $nginxProducts := slice
(dict "title" "NGINX One Console" "url" "/nginx-one" "type" "nginx-one")
(dict "title" "NGINX Plus" "url" "/nginx" "type" "nginx-one")
Expand All @@ -43,7 +43,7 @@
{{ $productIdentifier := index ((split $relPermalink "/")) 1 }}
{{ $productName := index $productMap $productIdentifier | default "Product Documentation" }}

<button class="product-selector__button" id="product-selector-button">
<button class="product-selector__button" id="product-selector-button" data-testid="product-selector__button">
{{/* product name and selector */}}
<span class="product-name">{{ $productName }}</span>
<span class="product-selector-button-icon">
Expand All @@ -52,7 +52,7 @@
</svg>
</span>
</button>
<div class="product-selector" id="product-selector">
<div class="product-selector" id="product-selector" data-testid="product-selector">
{{ $groupedProducts := dict
"nginx-one" (where $nginxProducts "type" "nginx-one")
"nginx-app-protect" (where $nginxProducts "type" "nginx-app-protect")
Expand All @@ -63,7 +63,7 @@
{{ range $orderedKeys }}
{{ $type := . }}
{{ $products := index $groupedProducts $type }}
<div class="product-selector-content" id="product-selector-content">
<div class="product-selector-content" id="product-selector-content" data-testid="product-selector-content">
<p>{{ $type | humanize | title | upper }}</p>
<ul>
{{ range $products }}
Expand All @@ -78,13 +78,13 @@
</div>

{{ if ( not ( in .Site.Params.buildtype "package" ) ) }}
<div class="header__search">
<div class="header__search" data-testid="header__search">
<!-- Standalone search box. -->
{{ partial "coveo-atomic-search.html" (dict "id" "search-standalone-header") }}
</div>
{{ end }}

<div class="header__f5sites">
<div class="header__f5sites" data-testid="header__f5sites">
{{ $f5Sites := slice
(dict "title" "DevCentral" "url" "https://community.f5.com/" "description" "Connect & learn in our hosted community")
(dict "title" "MyF5" "url" "https://my.f5.com/" "description" "Your key to everything F5, including support, registration keys, and subscriptions")
Expand All @@ -93,11 +93,11 @@

<ul class="navbar navbar-nav">
<li class="nav-item-explore active">
<button id="navbar-sites-button" class="button navbar-button">
<button id="navbar-sites-button" class="button navbar-button" data-testid="header__f5sites__button">
F5 Sites
<i id="navbar-sites-button-icon" class="link-chevron-icon fa-solid fa-chevron-down"></i>
</button>
<div class="dropdown-content" id="dropdown-content">
<div class="dropdown-content" id="dropdown-content" data-testid="header__f5sites-content">
<ul>
{{ range $f5Sites }}
<li>
Expand Down
9 changes: 5 additions & 4 deletions layouts/partials/sidebar-list.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
{{ $firstSection := .firstSection }}
{{ $idPrefix := .idPrefix }}
{{ with $firstSection }}
<ul class="sidebar__ul">
<ul class="sidebar__ul" data-testid="sidebar__ul">
{{ $pages := .Pages.ByWeight }}
{{ range $index, $p := $pages }}
{{- $onPage := eq $currentUrl $p.Permalink -}}
Expand All @@ -14,10 +14,11 @@
{{- $nextIndex := add $index 1 -}}
{{- $nextLink := index $pages $nextIndex -}}
{{ if eq $p.Kind "section" }}
<li class="sidebar__section">
<li class="sidebar__section" data-testid="sidebar__section">
<button
id="{{ $linkID }}"
class="sidebar__toggle {{ if $isAncestor }}sidebar__toggle--ancestor{{ end }}"
data-testid="sidebar__section__toggle"
aria-expanded="{{ $shouldExpand }}"
aria-controls="{{ $sectionID }}"
>
Expand All @@ -33,7 +34,7 @@
>
{{ if and .Content (gt (len .Pages) 0) }}
<ul>
<li class="sidebar__page">
<li class="sidebar__page" data-testid="sidebar__page">
<a
href="{{ $p.Permalink }}"
class="sidebar__link {{ if $onPage }}sidebar__link--current{{ end }}"
Expand All @@ -57,7 +58,7 @@
{{- $tocHasItems := (in $p.TableOfContents "<li>") -}}
{{- $pageHasTOC := (and $onPage $tocHasItems $p.Params.toc) -}}
{{- $tocID := printf "%stoc-%s" $idPrefix (urlize $p.Permalink) -}}
<li class="sidebar__page">
<li class="sidebar__page" data-testid="sidebar__page">
{{ if $pageHasTOC }}
<button
class="sidebar__toggle sidebar__link sidebar__link--current"
Expand Down
4 changes: 2 additions & 2 deletions layouts/partials/sidebar-v2.html
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@

<div class="sidebar__container">
<div class="sidebar__header">
<div class="sidebar__header" data-testid="sidebar__header">
<div>
<a href="{{ .Site.BaseURL | relLangURL }}" alt="NGINX Docs Home">
<img class="sidebar__img" src="{{ "/images/icons/NGINX-Docs-horiz-black-type.svg" | absURL }}" alt="NGINX Docs">
Expand All @@ -17,7 +17,7 @@
<!-- Standalone search box. -->
{{ partial "coveo-atomic-search.html" (dict "id" "search-standalone-sidebar") }}
</div>
<div class="sidebar__content">
<div class="sidebar__content" data-testid="sidebar__content">
<a class="skip-link" href="#maincontent">Skip Navigation</a>
{{ partial "sidebar-list.html" (dict
"firstSection" .FirstSection
Expand Down
2 changes: 1 addition & 1 deletion layouts/redoc/single.html
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{{ define "main" }}

<main class="content content__redocly">
<main class="content content__redocly" data-testid="content">
<div id="api-component">{{ .Content}}</div>
</main>

Expand Down
8 changes: 0 additions & 8 deletions tests/playwright.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,6 @@ export default defineConfig({
name: 'firefox',
use: { ...devices['Desktop Firefox'] },
},
{
name: 'webkit',
use: { ...devices['Desktop Safari'] },
},
{
name: 'Mobile Chrome',
use: { ...devices['Pixel 5'] },
},
],
webServer: {
command: `cd ../exampleSite && hugo mod get && hugo --gc --config hugo.toml,hugo.test.toml && hugo serve --port ${PORT} --config hugo.toml,hugo.test.toml`,
Expand Down
16 changes: 16 additions & 0 deletions tests/src/footer.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { expect, test } from '@playwright/test';

test.describe('Smoke test for footer', () => {
test.beforeEach(async ({ page }) => {
await page.goto('/');
});

test('should test footer renders', async ({ page }) => {
await expect(
await page.locator('data-testid=footer-f5-trademark').count()
).toBeTruthy();
await expect(
await page.locator('data-testid=footer-useful-links').count()
).toBeTruthy();
});
});
46 changes: 46 additions & 0 deletions tests/src/header.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import { expect, test } from '@playwright/test';

test.describe('Smoke test for header', () => {
test.beforeEach(async ({ page }) => {
await page.goto('/');
});

test('should test header renders', async ({ page }) => {
await expect(
await page.locator('data-testid=header__product-selector').count()
).toBeTruthy();
await expect(
await page.locator('data-testid=header__search').count()
).toBeTruthy();
await expect(
await page.locator('data-testid=header__f5sites').count()
).toBeTruthy();
});

test('should test product selector renders', async ({ page }) => {
// Check it renders
const productSelectorButton = await page.locator(
'data-testid=product-selector__button'
);
await productSelectorButton.click();
const productSelector = await page.locator('data-testid=product-selector');
await expect(productSelector.count()).toBeTruthy();

// Check it has four product groups. Usually this is frowned upon but is fine since it is a static number of groups for a while.
const productSelectorContent = productSelector.locator(
'data-testid=product-selector-content'
);
expect((await productSelectorContent.all()).length).toBe(4);
});

test('should test F5 Sites button works', async ({ page }) => {
const f5SitesButton = await page.locator(
'data-testid=header__f5sites__button'
);
await f5SitesButton.click();
const f5SitesContent = await page.locator(
'data-testid=header__f5sites-content'
);
await expect(f5SitesContent.count()).toBeTruthy();
});
});
13 changes: 13 additions & 0 deletions tests/src/product-landing.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { test } from '@playwright/test';
import { runSmokeTestOnPage } from './util';

test.describe('Smoke test for landing page', () => {
test('should test product landing page renders', async ({ page }) => {
const products = ['test-product', 'nginx'];

for (const product of products) {
await page.goto(`/${product}/`);
await runSmokeTestOnPage(page);
}
});
});
Loading