Skip to content

Commit 327f46a

Browse files
Tiffany Le-Nguyenascorbic
Tiffany Le-Nguyen
andauthored
chore: add e2e (#789)
* chore: move cypress out of demo * Update package.json * chore: add ci specific config * chore: fix testing library support * chore: fix config file location * chore: add data-testid for the lists * chore: change site to stub api request on dev * chore: add e2e tests * chore: add locale test * chore: get back actual call to shows * chore: fix test * chore: update snapidoos * chore: remove unused command Co-authored-by: Matt Kane <matt.kane@netlify.com> Co-authored-by: Matt Kane <matt.kane@netlify.com>
1 parent 7fe3923 commit 327f46a

14 files changed

+615
-115
lines changed

.eslintrc.js

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,5 +34,16 @@ module.exports = {
3434
env: {
3535
jest: true,
3636
},
37-
overrides: [...overrides],
37+
overrides: [
38+
...overrides,
39+
{
40+
files: ['cypress/**/*.spec.ts'],
41+
rules: {
42+
'max-nested-callbacks': 0,
43+
'promise/prefer-await-to-then': 0,
44+
'promise/always-return': 0,
45+
'promise/catch-or-return': 0,
46+
},
47+
},
48+
],
3849
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
/**
2+
* @see {@link https://nextjs.org/docs/advanced-features/custom-error-page}
3+
*/
4+
describe('Custom error pages', () => {
5+
it('should show custom 404 page on /404', () => {
6+
cy.visit('/404', {failOnStatusCode: false})
7+
cy.findByText('Custom 404 - Page Not Found')
8+
})
9+
10+
it('should show custom 500 page on /500', () => {
11+
cy.visit('/500', {failOnStatusCode: false})
12+
cy.findByText('Custom 500 - Server-side error occurred')
13+
})
14+
})

cypress/integration/default.spec.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
describe('Default site', () => {
2+
beforeEach(() => {
3+
cy.visit('/')
4+
})
5+
6+
it('loads home page', () => {
7+
cy.findByText('Next Demo!')
8+
cy.findByTestId("list-server-side").within(() => {
9+
cy.findAllByRole("link").should('have.length', 5)
10+
})
11+
12+
cy.findByTestId("list-dynamic-pages").within(() => {
13+
cy.findAllByRole("link").should('have.length', 3)
14+
})
15+
16+
cy.findByTestId("list-catch-all").within(() => {
17+
cy.findAllByRole("link").should('have.length', 3)
18+
})
19+
20+
cy.findByTestId("list-static").within(() => {
21+
cy.findAllByRole("link").should('have.length', 2)
22+
})
23+
})
24+
})
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
describe('Dynamic Routing', () => {
2+
it('loads page', () => {
3+
cy.visit('/shows/250')
4+
cy.findByRole('heading').should('contain', '250')
5+
cy.findByText('Kirby Buckets')
6+
})
7+
})

cypress/integration/headers.spec.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
describe('Headers', () => {
2+
it('should set headers from the next.config.js', () => {
3+
cy.request({
4+
url: '/',
5+
}).then((response) => {
6+
expect(response.headers).to.have.property('x-custom-header', 'my custom header value')
7+
})
8+
})
9+
})

cypress/integration/i18n.spec.ts

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
describe('Localization', () => {
2+
it('should use sub routing to determine current locale', () => {
3+
cy.visit('/');
4+
5+
cy.findByText('The current locale is en')
6+
7+
cy.visit('/fr')
8+
cy.findByText('The current locale is fr')
9+
})
10+
11+
it('should use the NEXT_LOCALE cookie to determine the default locale', () => {
12+
cy.setCookie('NEXT_LOCALE', 'fr')
13+
cy.visit('/');
14+
15+
cy.findByText('The current locale is fr')
16+
})
17+
18+
it('should use the NEXT_LOCALE cookie over Accept-Language header to determine the default locale', () => {
19+
// cy.setCookie('NEXT_LOCALE', 'en')
20+
cy.visit({
21+
url: '/',
22+
headers: {
23+
'Accept-Language': 'fr;q=0.9'
24+
}
25+
});
26+
cy.findByText('The current locale is fr')
27+
28+
cy.setCookie('NEXT_LOCALE', 'en')
29+
cy.visit({
30+
url: '/',
31+
headers: {
32+
'Accept-Language': 'fr;q=0.9'
33+
}
34+
});
35+
36+
cy.findByText('The current locale is en')
37+
})
38+
})

cypress/integration/images.spec.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
/**
2+
* @see {@link https://nextjs.org/docs/api-reference/next/image#required-props}
3+
*/
4+
describe('next/images', () => {
5+
it('should show static image from /public', () => {
6+
cy.visit('/')
7+
cy.findByRole('img').should('be.visible').and(($img) => {
8+
// "naturalWidth" and "naturalHeight" are set when the image loads
9+
expect(
10+
$img[0].naturalWidth,
11+
'image has natural width'
12+
).to.be.greaterThan(0)
13+
})
14+
})
15+
16+
it('should show image using next/image', () => {
17+
cy.visit('/image')
18+
cy.findByRole('img', { name: /shiba inu dog looks through a window/i })
19+
})
20+
})

cypress/integration/preview.spec.ts

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
describe('Preview Mode', () => {
2+
it('enters and exits preview mode', () => {
3+
// preview mode is off by default
4+
cy.visit('/previewTest')
5+
cy.findByText('Number: 4')
6+
7+
// enter preview mode
8+
cy.request('/api/enterPreview').then(
9+
(response) => {
10+
expect(response.body).to.have.property('name', 'preview mode')
11+
}
12+
)
13+
cy.visit('/previewTest')
14+
cy.findByText('Number: 3')
15+
16+
// exit preview mode
17+
cy.request('/api/exitPreview')
18+
cy.visit('/previewTest')
19+
cy.findByText('Number: 4')
20+
})
21+
})
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
describe('Rewrites and Redirects', () => {
2+
it('rewrites: points /old to /', () => {
3+
// preview mode is off by default
4+
cy.visit('/old')
5+
cy.findByText('Next Demo!')
6+
cy.url().should('eq', `${Cypress.config().baseUrl}/old/`)
7+
8+
// ensure headers are still set
9+
cy.request('/api/enterPreview').then(
10+
(response) => {
11+
expect(response.body).to.have.property('name', 'preview mode')
12+
}
13+
)
14+
})
15+
16+
it('redirects: redirects /redirectme to /', () => {
17+
cy.visit('/redirectme')
18+
cy.url().should('eq', `${Cypress.config().baseUrl}/`)
19+
}
20+
)
21+
})
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
describe('Trailing slash enabled', () => {
2+
it('should keep the trailing slash, i.e. points /old/ to /old/', () => {
3+
cy.visit('/old/')
4+
cy.url().should('eq', `${Cypress.config().baseUrl}/old/`)
5+
})
6+
7+
it('should put a trailing slash when there is none, i.e. points /old to /old/', () => {
8+
cy.visit('/old')
9+
cy.url().should('eq', `${Cypress.config().baseUrl}/old/`)
10+
})
11+
})

demo/next.config.js

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,23 @@ module.exports = {
66
defaultLocale: 'en',
77
locales: ['en', 'es', 'fr']
88
},
9-
// trailingSlash: true,
9+
async headers() {
10+
return [
11+
{
12+
source: '/',
13+
headers: [
14+
{
15+
key: 'x-custom-header',
16+
value: 'my custom header value',
17+
}
18+
],
19+
},
20+
]
21+
},
22+
trailingSlash: true,
1023
// Configurable site features _to_ support:
1124
// basePath: '/docs',
25+
// Rewrites allow you to map an incoming request path to a different destination path.
1226
async rewrites() {
1327
return {
1428
beforeFiles: [
@@ -18,5 +32,15 @@ module.exports = {
1832
}
1933
]
2034
}
21-
}
35+
},
36+
// Redirects allow you to redirect an incoming request path to a different destination path.
37+
async redirects() {
38+
return [
39+
{
40+
source: '/redirectme',
41+
destination: '/',
42+
permanent: true,
43+
},
44+
]
45+
},
2246
}

0 commit comments

Comments
 (0)