Add Playwright coverage for inner page layout at all viewports
This commit is contained in:
@@ -22,13 +22,14 @@ if ( hasSidebar() ) {
|
|||||||
?>
|
?>
|
||||||
|
|
||||||
<article class="<?php echo esc_attr( $classes ); ?>">
|
<article class="<?php echo esc_attr( $classes ); ?>">
|
||||||
|
<?php
|
||||||
|
// Centered intro section between the hero and the body content.
|
||||||
|
if ( get_field( 'intro' ) ) {
|
||||||
|
get_template_part( 'views/partials/page-intro' );
|
||||||
|
}
|
||||||
|
?>
|
||||||
<div class="entry-content <?php echo esc_attr( $clsEntry ); ?>">
|
<div class="entry-content <?php echo esc_attr( $clsEntry ); ?>">
|
||||||
<?php
|
<?php
|
||||||
// Centered intro section beneath the hero (rendered by header.php).
|
|
||||||
if ( get_field( 'intro' ) ) {
|
|
||||||
get_template_part( 'views/partials/page-intro' );
|
|
||||||
}
|
|
||||||
|
|
||||||
// Page body content
|
// Page body content
|
||||||
if ( have_posts() ) {
|
if ( have_posts() ) {
|
||||||
while ( have_posts() ) {
|
while ( have_posts() ) {
|
||||||
|
|||||||
Vendored
-23
@@ -625,10 +625,6 @@
|
|||||||
margin-top: calc(var(--spacing) * 2);
|
margin-top: calc(var(--spacing) * 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
.mt-3 {
|
|
||||||
margin-top: calc(var(--spacing) * 3);
|
|
||||||
}
|
|
||||||
|
|
||||||
.mt-4 {
|
.mt-4 {
|
||||||
margin-top: calc(var(--spacing) * 4);
|
margin-top: calc(var(--spacing) * 4);
|
||||||
}
|
}
|
||||||
@@ -1545,10 +1541,6 @@
|
|||||||
grid-column: span 8 / span 8;
|
grid-column: span 8 / span 8;
|
||||||
}
|
}
|
||||||
|
|
||||||
.sm\:mt-5 {
|
|
||||||
margin-top: calc(var(--spacing) * 5);
|
|
||||||
}
|
|
||||||
|
|
||||||
.sm\:mt-6 {
|
.sm\:mt-6 {
|
||||||
margin-top: calc(var(--spacing) * 6);
|
margin-top: calc(var(--spacing) * 6);
|
||||||
}
|
}
|
||||||
@@ -1605,11 +1597,6 @@
|
|||||||
font-size: var(--text-5xl);
|
font-size: var(--text-5xl);
|
||||||
line-height: var(--tw-leading, var(--text-5xl--line-height));
|
line-height: var(--tw-leading, var(--text-5xl--line-height));
|
||||||
}
|
}
|
||||||
|
|
||||||
.sm\:text-xl {
|
|
||||||
font-size: var(--text-xl);
|
|
||||||
line-height: var(--tw-leading, var(--text-xl--line-height));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (width >= 48rem) {
|
@media (width >= 48rem) {
|
||||||
@@ -1809,11 +1796,6 @@
|
|||||||
line-height: var(--tw-leading, var(--text-6xl--line-height));
|
line-height: var(--tw-leading, var(--text-6xl--line-height));
|
||||||
}
|
}
|
||||||
|
|
||||||
.lg\:text-lg {
|
|
||||||
font-size: var(--text-lg);
|
|
||||||
line-height: var(--tw-leading, var(--text-lg--line-height));
|
|
||||||
}
|
|
||||||
|
|
||||||
.lg\:text-xl {
|
.lg\:text-xl {
|
||||||
font-size: var(--text-xl);
|
font-size: var(--text-xl);
|
||||||
line-height: var(--tw-leading, var(--text-xl--line-height));
|
line-height: var(--tw-leading, var(--text-xl--line-height));
|
||||||
@@ -1893,11 +1875,6 @@
|
|||||||
font-size: var(--text-7xl);
|
font-size: var(--text-7xl);
|
||||||
line-height: var(--tw-leading, var(--text-7xl--line-height));
|
line-height: var(--tw-leading, var(--text-7xl--line-height));
|
||||||
}
|
}
|
||||||
|
|
||||||
.xl\:text-xl {
|
|
||||||
font-size: var(--text-xl);
|
|
||||||
line-height: var(--tw-leading, var(--text-xl--line-height));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (width >= 96rem) {
|
@media (width >= 96rem) {
|
||||||
|
|||||||
@@ -0,0 +1,125 @@
|
|||||||
|
import { expect, test } from "@playwright/test";
|
||||||
|
|
||||||
|
const pageUrl =
|
||||||
|
process.env.TEST_PAGE_URL ||
|
||||||
|
"http://community-works-collaborative.test/sample-page/";
|
||||||
|
|
||||||
|
const getBox = async (locator) => {
|
||||||
|
const box = await locator.boundingBox();
|
||||||
|
expect(box).not.toBeNull();
|
||||||
|
return box;
|
||||||
|
};
|
||||||
|
|
||||||
|
const expectNear = (actual, expected, tolerance = 3) => {
|
||||||
|
expect(Math.abs(actual - expected)).toBeLessThanOrEqual(tolerance);
|
||||||
|
};
|
||||||
|
|
||||||
|
test.describe("inner page layout", () => {
|
||||||
|
test("desktop: hero, intro, body render in order with the new media layers", async ({
|
||||||
|
page,
|
||||||
|
}) => {
|
||||||
|
const pageErrors = [];
|
||||||
|
page.on("pageerror", (err) => pageErrors.push(err.message));
|
||||||
|
|
||||||
|
await page.setViewportSize({ width: 1280, height: 900 });
|
||||||
|
await page.goto(pageUrl);
|
||||||
|
|
||||||
|
const hero = page.locator(".page-hero").first();
|
||||||
|
const intro = page.locator(".page-intro").first();
|
||||||
|
const content = page.locator(".entry-content").first();
|
||||||
|
|
||||||
|
await expect(hero).toBeVisible();
|
||||||
|
await expect(intro).toBeVisible();
|
||||||
|
await expect(content).toBeVisible();
|
||||||
|
|
||||||
|
// Order check: hero, then intro, then content.
|
||||||
|
const heroBox = await getBox(hero);
|
||||||
|
const introBox = await getBox(intro);
|
||||||
|
const contentBox = await getBox(content);
|
||||||
|
|
||||||
|
expect(heroBox.y).toBeLessThan(introBox.y);
|
||||||
|
expect(introBox.y).toBeLessThan(contentBox.y);
|
||||||
|
|
||||||
|
// Heading is rendered inside the hero.
|
||||||
|
await expect(hero.locator("h1").first()).toBeVisible();
|
||||||
|
|
||||||
|
// Intro is centered and capped at the max-w-3xl width.
|
||||||
|
const introInner = intro.locator(".content-wrapper").first();
|
||||||
|
const introInnerBox = await getBox(introInner);
|
||||||
|
expect(introInnerBox.width).toBeLessThanOrEqual(768 + 3);
|
||||||
|
|
||||||
|
// Page renders without JS errors.
|
||||||
|
expect(pageErrors).toEqual([]);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("mobile 402: hero, intro, body order and intro width", async ({
|
||||||
|
page,
|
||||||
|
}) => {
|
||||||
|
const pageErrors = [];
|
||||||
|
page.on("pageerror", (err) => pageErrors.push(err.message));
|
||||||
|
|
||||||
|
await page.setViewportSize({ width: 402, height: 874 });
|
||||||
|
await page.goto(pageUrl);
|
||||||
|
|
||||||
|
const hero = page.locator(".page-hero").first();
|
||||||
|
const intro = page.locator(".page-intro").first();
|
||||||
|
const content = page.locator(".entry-content").first();
|
||||||
|
|
||||||
|
await expect(hero).toBeVisible();
|
||||||
|
await expect(intro).toBeVisible();
|
||||||
|
await expect(content).toBeVisible();
|
||||||
|
|
||||||
|
const heroBox = await getBox(hero);
|
||||||
|
const introBox = await getBox(intro);
|
||||||
|
const contentBox = await getBox(content);
|
||||||
|
|
||||||
|
expect(heroBox.y).toBeLessThan(introBox.y);
|
||||||
|
expect(introBox.y).toBeLessThan(contentBox.y);
|
||||||
|
|
||||||
|
// Intro fits within the mobile viewport.
|
||||||
|
const introInner = intro.locator(".content-wrapper").first();
|
||||||
|
const introInnerBox = await getBox(introInner);
|
||||||
|
expect(introInnerBox.x + introInnerBox.width).toBeLessThanOrEqual(
|
||||||
|
402 + 3,
|
||||||
|
);
|
||||||
|
|
||||||
|
// No JS errors.
|
||||||
|
expect(pageErrors).toEqual([]);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("mobile 320: nothing clips horizontally", async ({ page }) => {
|
||||||
|
await page.setViewportSize({ width: 320, height: 800 });
|
||||||
|
await page.goto(pageUrl);
|
||||||
|
|
||||||
|
const hero = page.locator(".page-hero").first();
|
||||||
|
const intro = page.locator(".page-intro").first();
|
||||||
|
|
||||||
|
await expect(hero).toBeVisible();
|
||||||
|
await expect(intro).toBeVisible();
|
||||||
|
|
||||||
|
const heroBox = await getBox(hero);
|
||||||
|
const introBox = await getBox(intro);
|
||||||
|
|
||||||
|
expect(heroBox.x + heroBox.width).toBeLessThanOrEqual(320 + 3);
|
||||||
|
expect(introBox.x + introBox.width).toBeLessThanOrEqual(320 + 3);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("mobile 767: layout still holds before the desktop breakpoint", async ({
|
||||||
|
page,
|
||||||
|
}) => {
|
||||||
|
await page.setViewportSize({ width: 767, height: 900 });
|
||||||
|
await page.goto(pageUrl);
|
||||||
|
|
||||||
|
const hero = page.locator(".page-hero").first();
|
||||||
|
const intro = page.locator(".page-intro").first();
|
||||||
|
|
||||||
|
await expect(hero).toBeVisible();
|
||||||
|
await expect(intro).toBeVisible();
|
||||||
|
|
||||||
|
const heroBox = await getBox(hero);
|
||||||
|
const introBox = await getBox(intro);
|
||||||
|
|
||||||
|
expect(heroBox.x + heroBox.width).toBeLessThanOrEqual(767 + 3);
|
||||||
|
expect(introBox.x + introBox.width).toBeLessThanOrEqual(767 + 3);
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -18,7 +18,7 @@ if ( ! $intro ) {
|
|||||||
?>
|
?>
|
||||||
|
|
||||||
<section class="page-intro py-12 lg:py-20 text-center" aria-label="<?php echo esc_attr__( 'Page introduction' ); ?>">
|
<section class="page-intro py-12 lg:py-20 text-center" aria-label="<?php echo esc_attr__( 'Page introduction' ); ?>">
|
||||||
<div class="container mx-auto max-w-3xl content-wrapper">
|
<div class="mx-auto max-w-3xl content-wrapper">
|
||||||
<p class="page-intro__text text-lg lg:text-xl leading-relaxed text-dark">
|
<p class="page-intro__text text-lg lg:text-xl leading-relaxed text-dark">
|
||||||
<?php echo wp_kses_post( $intro ); ?>
|
<?php echo wp_kses_post( $intro ); ?>
|
||||||
</p>
|
</p>
|
||||||
|
|||||||
Reference in New Issue
Block a user