Skip to content
Merged
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
1 change: 1 addition & 0 deletions automation/run-e2e/docker/docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ services:
# Starts after mxbuild completes; "docker compose up --wait" blocks until healthy.
mxruntime:
image: mxruntime:${MENDIX_VERSION:?MENDIX_VERSION is required}
shm_size: "2gb"
depends_on:
mxbuild:
condition: service_completed_successfully
Expand Down
23 changes: 22 additions & 1 deletion automation/run-e2e/playwright.config.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,28 @@ module.exports = defineConfig({
baseURL: process.env.URL ? process.env.URL : "http://127.0.0.1:8080",

/* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */
trace: "on-first-retry"
trace: "on-first-retry",

launchOptions: {
args: [
"--disable-dev-shm-usage",
"--disable-extensions",
"--disable-background-networking",
"--disable-background-timer-throttling",
"--disable-renderer-backgrounding",
"--disable-sync",
"--disable-translate",
"--disable-default-apps",
"--disable-hang-monitor",
"--metrics-recording-only",
"--no-first-run",
"--font-render-hinting=none"
]
},

contextOptions: {
reducedMotion: "reduce"
}
},

/* Configure projects for major browsers */
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
37 changes: 17 additions & 20 deletions packages/pluggableWidgets/skiplink-web/e2e/SkipLink.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,63 +12,60 @@ test.beforeEach(async ({ page }) => {

test.describe("SkipLink:", function () {
test("skip link is present in DOM but initially hidden", async ({ page }) => {
// Skip link should be in the DOM but not visible
const skipLink = page.locator(".widget-skip-link").first();
await expect(skipLink).toBeAttached();
// Check initial styling (hidden)
const transform = await skipLink.evaluate(el => getComputedStyle(el).transform);
expect(transform).toContain("matrix(1, 0, 0, 1, 0, -48)");

// Element is translated above the viewport — its bottom edge should be at or above y=0
const rect = await skipLink.evaluate(el => el.getBoundingClientRect().toJSON());
expect(rect.bottom).toBeLessThanOrEqual(0);
});

test("skip link becomes visible when focused via keyboard", async ({ page }) => {
// Tab to focus the skip link (should be first focusable element)
const skipLink = page.locator(".widget-skip-link").first();
await page.keyboard.press("Tab");

await expect(skipLink).toBeFocused();
await page.waitForTimeout(1000);
// Check that it becomes visible when focused
const transform = await skipLink.evaluate(el => getComputedStyle(el).transform);
expect(transform).toContain("matrix(1, 0, 0, 1, 0, 0)")
// Element should now be within the viewport
const rect = await skipLink.evaluate(el => el.getBoundingClientRect().toJSON());
expect(rect.top).toBeGreaterThanOrEqual(0);
});

test("skip link navigates to main content when activated", async ({ page }) => {
// Tab to focus the skip link
await page.keyboard.press("Tab");

const skipLink = page.locator(".widget-skip-link").first();
await expect(skipLink).toBeFocused();

// Activate the skip link
await page.keyboard.press("Enter");

// Check that main content is now focused
const mainContent = page.locator("main");
await expect(mainContent).toBeFocused();
});

test("skip link has correct attributes and text", async ({ page }) => {
const skipLink = page.locator(".widget-skip-link").first();

// Check default text
await expect(skipLink).toHaveText("Skip to main content");

// Check href attribute
await expect(skipLink).toHaveAttribute("href", "#");

// Check CSS class
await expect(skipLink).toHaveClass("widget-skip-link mx-name-skipLink1");
});

test("visual comparison", async ({ page }) => {
// Tab to make skip link visible for screenshot
await page.keyboard.press("Tab");

const skipLink = page.locator(".widget-skip-link").first();
await expect(skipLink).toBeFocused();

// Visual comparison of focused skip link
await expect(skipLink).toHaveScreenshot("skiplink-focused.png");
});
});
});
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading