feat: add cypress

This commit is contained in:
Simon Emanuelsson
2024-02-29 10:35:40 +01:00
parent 57d7ab3092
commit b130ce11c6
16 changed files with 4645 additions and 17 deletions

View File

@@ -6,4 +6,5 @@ public/_static
app/core.css
app/scandic.css
.env.local.example
.prettierignore
.prettierignore
netlify.toml

View File

@@ -0,0 +1,17 @@
import type { Metadata } from "next"
import type { LangParams, LayoutArgs } from "@/types/params"
export const metadata: Metadata = {
title: "Test Site",
}
export default function RootLayout({
children,
params,
}: React.PropsWithChildren<LayoutArgs<LangParams>>) {
return (
<html lang={params.lang}>
<body>{children}</body>
</html>
)
}

View File

@@ -0,0 +1,15 @@
import type { Metadata } from "next"
export const metadata: Metadata = {
title: "Hello World",
}
export default function HelloWorldTestPage() {
return (
<main>
<header>
<h1>Hello World!</h1>
</header>
</main>
)
}

18
cypress.config.ts Normal file
View File

@@ -0,0 +1,18 @@
import { defineConfig } from "cypress"
import { config } from "dotenv"
config({ path: "./.env.local" })
export default defineConfig({
e2e: {
baseUrl: process.env.CYPRESS_BASE_URL,
setupNodeEvents(on, config) {},
},
component: {
devServer: {
bundler: "webpack",
framework: "next",
},
},
})

View File

@@ -0,0 +1,6 @@
describe("Hello World", () => {
it("should have an h1 tag", () => {
cy.visit("/en/test")
cy.get("h1").contains("Hello World")
})
})

View File

@@ -0,0 +1,5 @@
{
"name": "Using fixtures to represent data",
"email": "hello@cypress.io",
"body": "Fixtures are a great way to mock data for responses to routes"
}

View File

@@ -0,0 +1,37 @@
/// <reference types="cypress" />
// ***********************************************
// This example commands.ts shows you how to
// create various custom commands and overwrite
// existing commands.
//
// For more comprehensive examples of custom
// commands please read more here:
// https://on.cypress.io/custom-commands
// ***********************************************
//
//
// -- This is a parent command --
// Cypress.Commands.add('login', (email, password) => { ... })
//
//
// -- This is a child command --
// Cypress.Commands.add('drag', { prevSubject: 'element'}, (subject, options) => { ... })
//
//
// -- This is a dual command --
// Cypress.Commands.add('dismiss', { prevSubject: 'optional'}, (subject, options) => { ... })
//
//
// -- This will overwrite an existing command --
// Cypress.Commands.overwrite('visit', (originalFn, url, options) => { ... })
//
// declare global {
// namespace Cypress {
// interface Chainable {
// login(email: string, password: string): Chainable<void>
// drag(subject: string, options?: Partial<TypeOptions>): Chainable<Element>
// dismiss(subject: string, options?: Partial<TypeOptions>): Chainable<Element>
// visit(originalFn: CommandOriginalFn, url: string, options: Partial<VisitOptions>): Chainable<Element>
// }
// }
// }

View File

@@ -0,0 +1,14 @@
<!doctype html>
<html>
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width,initial-scale=1.0" />
<title>Components App</title>
<!-- Used by Next.js to inject CSS. -->
<div id="__next_css__DO_NOT_USE__"></div>
</head>
<body>
<div data-cy-root></div>
</body>
</html>

View File

@@ -0,0 +1,39 @@
// ***********************************************************
// This example support/component.ts is processed and
// loaded automatically before your test files.
//
// This is a great place to put global configuration and
// behavior that modifies Cypress.
//
// You can change the location of this file or turn off
// automatically serving support files with the
// 'supportFile' configuration option.
//
// You can read more here:
// https://on.cypress.io/configuration
// ***********************************************************
// Import commands.js using ES2015 syntax:
import "./commands"
// Alternatively you can use CommonJS syntax:
// require('./commands')
import { mount } from "cypress/react18"
// Augment the Cypress namespace to include type definitions for
// your custom command.
// Alternatively, can be defined in cypress/support/component.d.ts
// with a <reference path="./component" /> at the top of your spec.
declare global {
namespace Cypress {
interface Chainable {
mount: typeof mount
}
}
}
Cypress.Commands.add("mount", mount)
// Example use:
// cy.mount(<MyComponent />)

20
cypress/support/e2e.ts Normal file
View File

@@ -0,0 +1,20 @@
// ***********************************************************
// This example support/e2e.ts is processed and
// loaded automatically before your test files.
//
// This is a great place to put global configuration and
// behavior that modifies Cypress.
//
// You can change the location of this file or turn off
// automatically serving support files with the
// 'supportFile' configuration option.
//
// You can read more here:
// https://on.cypress.io/configuration
// ***********************************************************
// Import commands.js using ES2015 syntax:
import "./commands"
// Alternatively you can use CommonJS syntax:
// require('./commands')

8
env/server.ts vendored
View File

@@ -3,28 +3,32 @@ import { z } from "zod"
export const env = createEnv({
server: {
ADOBE_SCRIPT_SRC: z.string().optional(),
BUILD_ID: z.string().default("64rYXBu8o2eHp0Jf"),
CMS_ACCESS_TOKEN: z.string(),
CMS_API_KEY: z.string(),
CMS_ENVIRONMENT: z.enum(["development", "production", "staging", "test"]),
CMS_URL: z.string(),
CMS_PREVIEW_URL: z.string(),
CMS_PREVIEW_TOKEN: z.string(),
CYPRESS_BASE_URL: z.string().default("http://127.0.0.1:3000"),
NODE_ENV: z.enum(["development", "test", "production"]),
PRINT_QUERY: z.boolean().default(false),
REVALIDATE_SECRET: z.string(),
ADOBE_SCRIPT_SRC: z.string().optional(),
},
emptyStringAsUndefined: true,
runtimeEnv: {
ADOBE_SCRIPT_SRC: process.env.ADOBE_SCRIPT_SRC,
BUILD_ID: process.env.BUILD_ID,
CMS_ACCESS_TOKEN: process.env.CMS_ACCESS_TOKEN,
CMS_API_KEY: process.env.CMS_API_KEY,
CMS_ENVIRONMENT: process.env.CMS_ENVIRONMENT,
CMS_URL: process.env.CMS_URL,
CMS_PREVIEW_URL: process.env.CMS_PREVIEW_URL,
CMS_PREVIEW_TOKEN: process.env.CMS_PREVIEW_TOKEN,
CYPRESS_BASE_URL: process.env.CYPRESS_TEST_URL,
NODE_ENV: process.env.NODE_ENV,
PRINT_QUERY: process.env.PRINT_QUERY,
REVALIDATE_SECRET: process.env.REVALIDATE_SECRET,
ADOBE_SCRIPT_SRC: process.env.ADOBE_SCRIPT_SRC,
},
})

View File

@@ -1,4 +1,3 @@
import ContentstackLivePreview from "@contentstack/live-preview-utils"
import { NextResponse } from "next/server"
import type { NextRequest } from "next/server"
@@ -70,6 +69,6 @@ export const config = {
* - _next/image (image optimization files)
* - favicon.ico (favicon file)
*/
"/((?!api|_next/static|_next/image|_static|imageVault|contentassets|favicon.ico).*)",
"/((?!api|_next/static|_next/image|_static|imageVault|contentassets|favicon.ico|en/test).*)",
],
}

View File

@@ -1,2 +1,23 @@
[build]
command = "npm run build"
publish = ".next"
[[plugins]]
package = "@netlify/plugin-nextjs"
package = "netlify-plugin-cypress"
[plugins.inputs]
configFile = "cypress.config.ts"
[plugins.inputs.postBuild]
enable = true
start = "npm start"
wait-on = "http://127.0.0.1:3000/en/test"
wait-on-timeout = "30" # seconds
[build.environment]
# cache Cypress binary in local "node_modules" folder
# so Netlify caches it
CYPRESS_CACHE_FOLDER = "./node_modules/CypressBinary"
# set TERM variable for terminal output
TERM = "xterm"
[[plugins]]
package = "@netlify/plugin-nextjs"

View File

@@ -8,6 +8,11 @@ jiti("./env/client")
/** @type {import('next').NextConfig} */
const nextConfig = {
eslint: { ignoreDuringBuilds: true },
generateBuildId: async () => {
return process.env.BUILD_ID
},
images: {
remotePatterns: [
{
@@ -18,6 +23,14 @@ const nextConfig = {
],
},
logging: {
fetches: {
fullUrl: true,
},
},
output: "standalone",
webpack: function (config, options) {
config.module.rules.push({
test: /\.(graphql|gql)/,
@@ -25,14 +38,8 @@ const nextConfig = {
loader: "graphql-tag/loader",
})
return config;
return config
},
logging: {
fetches: {
fullUrl: true,
},
},
};
}
export default nextConfig

4416
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -4,11 +4,16 @@
"private": true,
"type": "module",
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start",
"dev": "next dev",
"lint": "next lint && tsc",
"prepare": "husky install"
"prepare": "husky install",
"start": "node .next/standalone/server.js",
"test:component": "cypress open --component",
"test:component:headless": "cypress run --component",
"test:e2e": "start-server-and-test test:setup http://127.0.0.1:3000/en/test \"cypress open --e2e\"",
"test:e2e:headless": "start-server-and-test test:setup http://127.0.0.1:3000/en/test \"cypress run --e2e\"",
"test:setup": "npm run build && npm run start"
},
"dependencies": {
"@contentstack/live-preview-utils": "^1.4.0",
@@ -28,12 +33,16 @@
"@types/node": "^20",
"@types/react": "^18",
"@types/react-dom": "^18",
"cypress": "^13.6.6",
"dotenv": "^16.4.5",
"eslint": "^8",
"eslint-config-next": "^14.0.4",
"husky": "^9.0.11",
"jiti": "^1.21.0",
"lint-staged": "^15.2.2",
"netlify-plugin-cypress": "^2.2.1",
"prettier": "^3.2.5",
"start-server-and-test": "^2.0.3",
"typescript": "^5"
},
"engines": {