Skip to content

add e2e for next/head and next/amp in pages router #845

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

Merged
merged 4 commits into from
May 5, 2025
Merged
Show file tree
Hide file tree
Changes from 3 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
39 changes: 39 additions & 0 deletions examples/pages-router/src/pages/amp/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/*
* When doing `next build` you would get the error below:
* TypeScript error: Property 'amp-timeago' does not exist on type 'JSX.IntrinsicElements'.
* https://stackoverflow.com/questions/50585952/property-amp-img-does-not-exist-on-type-jsx-intrinsicelements/50601125#50601125
* The workaround in that SO post doesn't work in this (mono)repo so I ended up using @ts-expect-error and @ts-ignore
*
*/

export const config = { amp: true };

export async function getServerSideProps() {
return {
props: {
time: new Date().toISOString(),
},
};
}

function MyAmpPage({ time }: { time: string }) {
const date = new Date(time);

return (
<div>
<p>Some time: {date.toJSON()}</p>
{/* @ts-expect-error AMP Component not recognized by TypeScript */}
<amp-timeago
width="0"
height="15"
datetime={date.toJSON()}
layout="responsive"
data-testid="amp-timeago"
>
.{/* @ts-ignore */}
</amp-timeago>
</div>
);
}

export default MyAmpPage;
34 changes: 34 additions & 0 deletions examples/pages-router/src/pages/head/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import type { InferGetServerSidePropsType } from "next";
import Head from "next/head";

export async function getServerSideProps() {
return {
props: {
time: new Date().toISOString(),
envVar: process.env.SOME_PROD_VAR,
},
};
}

export default function Page({
time,
envVar,
}: InferGetServerSidePropsType<typeof getServerSideProps>) {
return (
<div>
<Head>
<title>OpenNext head</title>
<meta
property="og:title"
content={`OpenNext pages router head ${envVar}`}
/>
<meta property="time" content={time} />
<meta
name="description"
content="OpenNext takes the Next.js build output and converts it into packages that can be deployed across a variety of environments. Natively OpenNext has support for AWS Lambda, Cloudflare, and classic Node.js Server."
/>
</Head>
<p>This is a page!</p>
</div>
);
}
11 changes: 11 additions & 0 deletions packages/tests-e2e/tests/pagesRouter/amp.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { expect, test } from "@playwright/test";

test.describe("next/amp", () => {
test("should load and display the timeago component", async ({ page }) => {
await page.goto("/amp");
const timeago = await page.getByTestId("amp-timeago").textContent();
expect(timeago).toBe("just now");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How precise is it ?
Could it display a 1s ago ?

Copy link
Contributor Author

@sommeeeer sommeeeer May 3, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How precise is it ?

In theory it should be always showing just now here as the value is calculated at render time, and that wont take many ms. Its using format() from timeago.js under the hood, and it will show just now until it reaches 10s, then it will start showing 10 seconds ago.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can add a comment about it in the test.

const htmlEl = page.locator("html");
await expect(htmlEl).toHaveAttribute("amp");
});
});
27 changes: 27 additions & 0 deletions packages/tests-e2e/tests/pagesRouter/head.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { expect, test } from "@playwright/test";

test.describe("next/head", () => {
test("should have the correct title", async ({ page }) => {
await page.goto("/head");
const title = await page.title();
expect(title).toBe("OpenNext head");
});
test("should have the correct meta tags", async ({ page }) => {
await page.goto("/head");
const ogTitle = await page
.locator('meta[property="og:title"]')
.getAttribute("content");
const ogDesc = await page
.locator('meta[name="description"]')
.getAttribute("content");
const time = await page
.locator('meta[property="time"]')
.getAttribute("content");
expect(ogTitle).toBe("OpenNext pages router head bar");
expect(ogDesc).toBe(
"OpenNext takes the Next.js build output and converts it into packages that can be deployed across a variety of environments. Natively OpenNext has support for AWS Lambda, Cloudflare, and classic Node.js Server.",
);

expect(new Date(time!).getTime()).toBeLessThan(Date.now());
});
});
Loading