mirror of
https://github.com/terribleplan/next.js.git
synced 2024-01-19 02:48:18 +00:00
Incorporate styled-jsx (#420)
* integrate styled-jsx * define styles of pages with styled-jsx * bump styled-jsx * bump styled-jsx * error-debug: fix style * bump styled-jsx * fix examples to use styled-jsx * bump styled-jsx
This commit is contained in:
parent
26c485a22f
commit
a87ef1a7af
|
@ -1,21 +0,0 @@
|
||||||
import React, { Component } from 'react'
|
|
||||||
import { style } from 'next/css'
|
|
||||||
|
|
||||||
export default class CrazyCSS extends Component {
|
|
||||||
spans () {
|
|
||||||
const out = []
|
|
||||||
for (let i = 0; i < 1000; i++) {
|
|
||||||
out.push(<span key={i} class={spanStyles[`padding-${i}`]}>This is ${i}</span>)
|
|
||||||
}
|
|
||||||
return out
|
|
||||||
}
|
|
||||||
|
|
||||||
render () {
|
|
||||||
return <div>{this.spans()}</div>
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const spanStyles = {}
|
|
||||||
for (let i = 0; i < 1000; i++) {
|
|
||||||
spanStyles[`padding-${i}`] = style({ padding: i })
|
|
||||||
}
|
|
|
@ -1,19 +1,19 @@
|
||||||
import React from 'react'
|
import React from 'react'
|
||||||
import style from 'next/css'
|
|
||||||
|
|
||||||
export default () => (
|
export default () => (
|
||||||
<div className={styles}>
|
<div className='hello'>
|
||||||
<p>Hello World</p>
|
<p>Hello World</p>
|
||||||
|
<style jsx>{`
|
||||||
|
.hello {
|
||||||
|
font: 15px Helvetica, Arial, sans-serif;
|
||||||
|
background: #eee;
|
||||||
|
padding: 100px;
|
||||||
|
text-align: center;
|
||||||
|
transition: 100ms ease-in background;
|
||||||
|
}
|
||||||
|
.hello:hover {
|
||||||
|
background: #ccc;
|
||||||
|
}
|
||||||
|
`}</style>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
|
||||||
const styles = style({
|
|
||||||
font: '15px Helvetica, Arial, sans-serif',
|
|
||||||
background: '#eee',
|
|
||||||
padding: '100px',
|
|
||||||
textAlign: 'center',
|
|
||||||
transition: '100ms ease-in background',
|
|
||||||
':hover': {
|
|
||||||
background: '#ccc'
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
|
@ -1,11 +1,13 @@
|
||||||
import React from 'react'
|
import React from 'react'
|
||||||
import style from 'next/css'
|
|
||||||
|
|
||||||
export default ({ children }) => (
|
export default ({ children }) => (
|
||||||
<p className={styles}>{children}</p>
|
<p>
|
||||||
|
{children}
|
||||||
|
<style jsx>{`
|
||||||
|
p {
|
||||||
|
font: 13px Helvetica, Arial;
|
||||||
|
margin: 10px 0;
|
||||||
|
}
|
||||||
|
`}</style>
|
||||||
|
</p>
|
||||||
)
|
)
|
||||||
|
|
||||||
const styles = style({
|
|
||||||
font: '13px Helvetica, Arial',
|
|
||||||
margin: '10px 0'
|
|
||||||
})
|
|
||||||
|
|
|
@ -1,21 +1,21 @@
|
||||||
import React from 'react'
|
import React from 'react'
|
||||||
import style from 'next/css'
|
|
||||||
|
|
||||||
export default ({ title, children }) => (
|
export default ({ title, children }) => (
|
||||||
<div className={mainStyle}>
|
<div className='main'>
|
||||||
<h1 className={titleStyle}>{ title }</h1>
|
<h1>{ title }</h1>
|
||||||
{ children }
|
{ children }
|
||||||
|
<style jsx>{`
|
||||||
|
.main {
|
||||||
|
font: 15px Helvetica, Arial;
|
||||||
|
border: 1px solid #eee;
|
||||||
|
padding: 0 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1 {
|
||||||
|
font-size: 16px;
|
||||||
|
font-weight: bold;
|
||||||
|
margin: 10px 0;
|
||||||
|
}
|
||||||
|
`}</style>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
|
||||||
const mainStyle = style({
|
|
||||||
font: '15px Helvetica, Arial',
|
|
||||||
border: '1px solid #eee',
|
|
||||||
padding: '0 10px'
|
|
||||||
})
|
|
||||||
|
|
||||||
const titleStyle = style({
|
|
||||||
fontSize: '16px',
|
|
||||||
fontWeight: 'bold',
|
|
||||||
margin: '10px 0'
|
|
||||||
})
|
|
||||||
|
|
|
@ -1,16 +1,15 @@
|
||||||
import React from 'react'
|
import React from 'react'
|
||||||
import P from '../components/paragraph'
|
import P from '../components/paragraph'
|
||||||
import Post from '../components/post'
|
import Post from '../components/post'
|
||||||
import style from 'next/css'
|
|
||||||
|
|
||||||
export default () => (
|
export default () => (
|
||||||
<div className={styles.main}>
|
<div className='main'>
|
||||||
<Post title='My first blog post'>
|
<Post title='My first blog post'>
|
||||||
<P>Hello there</P>
|
<P>Hello there</P>
|
||||||
<P>This is an example of a componentized blog post</P>
|
<P>This is an example of a componentized blog post</P>
|
||||||
</Post>
|
</Post>
|
||||||
|
|
||||||
<Hr />
|
<hr />
|
||||||
|
|
||||||
<Post title='My second blog post'>
|
<Post title='My second blog post'>
|
||||||
<P>Hello there</P>
|
<P>Hello there</P>
|
||||||
|
@ -18,31 +17,30 @@ export default () => (
|
||||||
<P>Wa-hoo!</P>
|
<P>Wa-hoo!</P>
|
||||||
</Post>
|
</Post>
|
||||||
|
|
||||||
<Hr />
|
<hr />
|
||||||
|
|
||||||
<Post title='The final blog post'>
|
<Post title='The final blog post'>
|
||||||
<P>C'est fin</P>
|
<P>C'est fin</P>
|
||||||
</Post>
|
</Post>
|
||||||
|
|
||||||
|
<style jsx>{`
|
||||||
|
.main {
|
||||||
|
margin: auto;
|
||||||
|
max-width: 420px;
|
||||||
|
padding: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
hr {
|
||||||
|
width: 100px;
|
||||||
|
border-width: 0;
|
||||||
|
margin: 20px auto;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
hr::before {
|
||||||
|
content: "***";
|
||||||
|
color: #ccc;
|
||||||
|
}
|
||||||
|
`}</style>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
|
||||||
const Hr = () => <hr className={styles.hr} />
|
|
||||||
|
|
||||||
const styles = {
|
|
||||||
main: style({
|
|
||||||
margin: 'auto',
|
|
||||||
maxWidth: '420px',
|
|
||||||
padding: '10px'
|
|
||||||
}),
|
|
||||||
|
|
||||||
hr: style({
|
|
||||||
width: '100px',
|
|
||||||
borderWidth: 0,
|
|
||||||
margin: '20px auto',
|
|
||||||
textAlign: 'center',
|
|
||||||
'::before': {
|
|
||||||
content: '"***"',
|
|
||||||
color: '#ccc'
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
|
@ -65,6 +65,7 @@
|
||||||
"send": "0.14.1",
|
"send": "0.14.1",
|
||||||
"source-map-support": "0.4.6",
|
"source-map-support": "0.4.6",
|
||||||
"strip-ansi": "3.0.1",
|
"strip-ansi": "3.0.1",
|
||||||
|
"styled-jsx": "0.2.1",
|
||||||
"url": "0.11.0",
|
"url": "0.11.0",
|
||||||
"webpack": "1.14.0",
|
"webpack": "1.14.0",
|
||||||
"webpack-dev-middleware": "1.9.0",
|
"webpack-dev-middleware": "1.9.0",
|
||||||
|
|
|
@ -1,7 +1,5 @@
|
||||||
import React from 'react'
|
import React from 'react'
|
||||||
import ansiHTML from 'ansi-html'
|
import ansiHTML from 'ansi-html'
|
||||||
import Head from 'next/head'
|
|
||||||
import style from 'next/css'
|
|
||||||
|
|
||||||
export default class ErrorDebug extends React.Component {
|
export default class ErrorDebug extends React.Component {
|
||||||
static getInitialProps ({ err }) {
|
static getInitialProps ({ err }) {
|
||||||
|
@ -12,21 +10,47 @@ export default class ErrorDebug extends React.Component {
|
||||||
render () {
|
render () {
|
||||||
const { name, message, stack, path } = this.props
|
const { name, message, stack, path } = this.props
|
||||||
|
|
||||||
return <div className={styles.errorDebug}>
|
return <div className='errorDebug'>
|
||||||
<Head>
|
{path ? <div className='heading'>Error in {path}</div> : null}
|
||||||
<style dangerouslySetInnerHTML={{ __html: `
|
|
||||||
body {
|
|
||||||
background: #a6004c;
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
`}} />
|
|
||||||
</Head>
|
|
||||||
{path ? <div className={styles.heading}>Error in {path}</div> : null}
|
|
||||||
{
|
{
|
||||||
name === 'ModuleBuildError'
|
name === 'ModuleBuildError'
|
||||||
? <pre className={styles.message} dangerouslySetInnerHTML={{ __html: ansiHTML(encodeHtml(message)) }} />
|
? <pre className='message' dangerouslySetInnerHTML={{ __html: ansiHTML(encodeHtml(message)) }} />
|
||||||
: <pre className={styles.message}>{stack}</pre>
|
: <pre className='message'>{stack}</pre>
|
||||||
}
|
}
|
||||||
|
<style jsx global>{`
|
||||||
|
body {
|
||||||
|
background: #a6004c;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
`}</style>
|
||||||
|
<style jsx>{`
|
||||||
|
.errorDebug {
|
||||||
|
height: 100vh;
|
||||||
|
padding: 16px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.message {
|
||||||
|
font-family: "SF Mono", "Roboto Mono", "Fira Mono", menlo-regular, monospace;
|
||||||
|
font-size: 10px;
|
||||||
|
color: #fbe7f1;
|
||||||
|
margin: 0;
|
||||||
|
white-space: pre-wrap;
|
||||||
|
word-wrap: break-word;
|
||||||
|
}
|
||||||
|
|
||||||
|
.heading {
|
||||||
|
font-family: -apple-system, BlinkMacSystemFont, Roboto, "Segoe UI", "Fira Sans", Avenir, "Helvetica Neue", "Lucida Grande", sans-serif;
|
||||||
|
font-size: 13px;
|
||||||
|
font-weight: bold;
|
||||||
|
color: #ff84bf;
|
||||||
|
margin-bottom: 20pxl
|
||||||
|
}
|
||||||
|
`}</style>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -35,40 +59,6 @@ const encodeHtml = str => {
|
||||||
return str.replace(/</g, '<').replace(/>/g, '>')
|
return str.replace(/</g, '<').replace(/>/g, '>')
|
||||||
}
|
}
|
||||||
|
|
||||||
const styles = {
|
|
||||||
body: style({
|
|
||||||
background: '#a6004c',
|
|
||||||
margin: 0
|
|
||||||
}),
|
|
||||||
|
|
||||||
errorDebug: style({
|
|
||||||
height: '100vh',
|
|
||||||
padding: '16px',
|
|
||||||
boxSizing: 'border-box',
|
|
||||||
display: 'flex',
|
|
||||||
flexDirection: 'column',
|
|
||||||
alignItems: 'center',
|
|
||||||
justifyContent: 'center'
|
|
||||||
}),
|
|
||||||
|
|
||||||
message: style({
|
|
||||||
fontFamily: '"SF Mono", "Roboto Mono", "Fira Mono", menlo-regular, monospace',
|
|
||||||
fontSize: '10px',
|
|
||||||
color: '#fbe7f1',
|
|
||||||
margin: 0,
|
|
||||||
whiteSpace: 'pre-wrap',
|
|
||||||
wordWrap: 'break-word'
|
|
||||||
}),
|
|
||||||
|
|
||||||
heading: style({
|
|
||||||
fontFamily: '-apple-system, BlinkMacSystemFont, Roboto, "Segoe UI", "Fira Sans", Avenir, "Helvetica Neue", "Lucida Grande", sans-serif',
|
|
||||||
fontSize: '13px',
|
|
||||||
fontWeight: 'bold',
|
|
||||||
color: '#ff84bf',
|
|
||||||
marginBottom: '20px'
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// see color definitions of babel-code-frame:
|
// see color definitions of babel-code-frame:
|
||||||
// https://github.com/babel/babel/blob/master/packages/babel-code-frame/src/index.js
|
// https://github.com/babel/babel/blob/master/packages/babel-code-frame/src/index.js
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
import React from 'react'
|
import React from 'react'
|
||||||
import style from 'next/css'
|
|
||||||
|
|
||||||
export default class Error extends React.Component {
|
export default class Error extends React.Component {
|
||||||
static getInitialProps ({ res, xhr }) {
|
static getInitialProps ({ res, xhr }) {
|
||||||
|
@ -13,54 +12,53 @@ export default class Error extends React.Component {
|
||||||
? 'This page could not be found'
|
? 'This page could not be found'
|
||||||
: (statusCode ? 'Internal Server Error' : 'An unexpected error has occurred')
|
: (statusCode ? 'Internal Server Error' : 'An unexpected error has occurred')
|
||||||
|
|
||||||
return <div className={styles.error}>
|
return <div className='error'>
|
||||||
<div className={styles.text}>
|
<div>
|
||||||
{statusCode ? <h1 className={styles.h1}>{statusCode}</h1> : null}
|
{statusCode ? <h1>{statusCode}</h1> : null}
|
||||||
<div className={styles.desc}>
|
<div className='desc'>
|
||||||
<h2 className={styles.h2}>{title}.</h2>
|
<h2>{title}.</h2>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<style jsx>{`
|
||||||
|
.error {
|
||||||
|
color: #000;
|
||||||
|
background: #fff;
|
||||||
|
top: 0;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
position: absolute;
|
||||||
|
font-family: -apple-system, BlinkMacSystemFont, Roboto, "Segoe UI", "Fira Sans", Avenir, "Helvetica Neue", "Lucida Grande", sans-serif;
|
||||||
|
text-align: center;
|
||||||
|
padding-top: 20%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.desc {
|
||||||
|
display: inline-block;
|
||||||
|
text-align: left;
|
||||||
|
line-height: 49px;
|
||||||
|
height: 49px;
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1 {
|
||||||
|
display: inline-block;
|
||||||
|
border-right: 1px solid rgba(0, 0, 0,.3);
|
||||||
|
margin: 0;
|
||||||
|
margin-right: 20px;
|
||||||
|
padding: 10px 23px;
|
||||||
|
font-size: 24px;
|
||||||
|
font-weight: 500;
|
||||||
|
vertical-align: top;
|
||||||
|
}
|
||||||
|
|
||||||
|
h2 {
|
||||||
|
font-size: 14px;
|
||||||
|
font-weight: normal;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
`}</style>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const styles = {
|
|
||||||
error: style({
|
|
||||||
color: '#000',
|
|
||||||
background: '#fff',
|
|
||||||
top: 0,
|
|
||||||
bottom: 0,
|
|
||||||
left: 0,
|
|
||||||
right: 0,
|
|
||||||
position: 'absolute',
|
|
||||||
fontFamily: '-apple-system, BlinkMacSystemFont, Roboto, "Segoe UI", "Fira Sans", Avenir, "Helvetica Neue", "Lucida Grande", sans-serif',
|
|
||||||
textAlign: 'center',
|
|
||||||
paddingTop: '20%'
|
|
||||||
}),
|
|
||||||
|
|
||||||
desc: style({
|
|
||||||
display: 'inline-block',
|
|
||||||
textAlign: 'left',
|
|
||||||
lineHeight: '49px',
|
|
||||||
height: '49px',
|
|
||||||
verticalAlign: 'middle'
|
|
||||||
}),
|
|
||||||
|
|
||||||
h1: style({
|
|
||||||
display: 'inline-block',
|
|
||||||
borderRight: '1px solid rgba(0, 0, 0,.3)',
|
|
||||||
margin: 0,
|
|
||||||
marginRight: '20px',
|
|
||||||
padding: '10px 23px',
|
|
||||||
fontSize: '24px',
|
|
||||||
fontWeight: 500,
|
|
||||||
verticalAlign: 'top'
|
|
||||||
}),
|
|
||||||
|
|
||||||
h2: style({
|
|
||||||
fontSize: '14px',
|
|
||||||
fontWeight: 'normal',
|
|
||||||
margin: 0,
|
|
||||||
padding: 0
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
|
@ -120,7 +120,8 @@ export default async function createCompiler (dir, { dev = false } = {}) {
|
||||||
require.resolve('babel-plugin-module-resolver'),
|
require.resolve('babel-plugin-module-resolver'),
|
||||||
{
|
{
|
||||||
alias: {
|
alias: {
|
||||||
'ansi-html': require.resolve('ansi-html')
|
'ansi-html': require.resolve('ansi-html'),
|
||||||
|
'styled-jsx/style': require.resolve('styled-jsx/style')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
@ -143,6 +144,7 @@ export default async function createCompiler (dir, { dev = false } = {}) {
|
||||||
require.resolve('babel-plugin-transform-object-rest-spread'),
|
require.resolve('babel-plugin-transform-object-rest-spread'),
|
||||||
require.resolve('babel-plugin-transform-class-properties'),
|
require.resolve('babel-plugin-transform-class-properties'),
|
||||||
require.resolve('babel-plugin-transform-runtime'),
|
require.resolve('babel-plugin-transform-runtime'),
|
||||||
|
require.resolve('styled-jsx/babel'),
|
||||||
[
|
[
|
||||||
require.resolve('babel-plugin-module-resolver'),
|
require.resolve('babel-plugin-module-resolver'),
|
||||||
{
|
{
|
||||||
|
@ -154,7 +156,8 @@ export default async function createCompiler (dir, { dev = false } = {}) {
|
||||||
'next/prefetch': require.resolve('../../lib/prefetch'),
|
'next/prefetch': require.resolve('../../lib/prefetch'),
|
||||||
'next/css': require.resolve('../../lib/css'),
|
'next/css': require.resolve('../../lib/css'),
|
||||||
'next/head': require.resolve('../../lib/head'),
|
'next/head': require.resolve('../../lib/head'),
|
||||||
'next/document': require.resolve('../../server/document')
|
'next/document': require.resolve('../../server/document'),
|
||||||
|
'styled-jsx/style': require.resolve('styled-jsx/style')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import React, { Component, PropTypes } from 'react'
|
import React, { Component, PropTypes } from 'react'
|
||||||
import htmlescape from 'htmlescape'
|
import htmlescape from 'htmlescape'
|
||||||
import { renderStatic } from 'glamor/server'
|
import { renderStatic } from 'glamor/server'
|
||||||
|
import flush from 'styled-jsx/server'
|
||||||
|
|
||||||
export default class Document extends Component {
|
export default class Document extends Component {
|
||||||
static getInitialProps ({ renderPage }) {
|
static getInitialProps ({ renderPage }) {
|
||||||
|
@ -10,7 +11,8 @@ export default class Document extends Component {
|
||||||
head = page.head
|
head = page.head
|
||||||
return page.html
|
return page.html
|
||||||
})
|
})
|
||||||
const nextCSS = { css, ids }
|
const styles = flush()
|
||||||
|
const nextCSS = { css, ids, styles }
|
||||||
return { html, head, nextCSS }
|
return { html, head, nextCSS }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -48,7 +50,8 @@ export class Head extends Component {
|
||||||
const { head, nextCSS } = this.context._documentProps
|
const { head, nextCSS } = this.context._documentProps
|
||||||
return <head>
|
return <head>
|
||||||
{(head || []).map((h, i) => React.cloneElement(h, { key: i }))}
|
{(head || []).map((h, i) => React.cloneElement(h, { key: i }))}
|
||||||
{nextCSS ? <style dangerouslySetInnerHTML={{ __html: nextCSS.css }} /> : null}
|
{nextCSS && nextCSS.css ? <style dangerouslySetInnerHTML={{ __html: nextCSS.css }} /> : null}
|
||||||
|
{nextCSS && nextCSS.styles ? nextCSS.styles : null}
|
||||||
{this.props.children}
|
{this.props.children}
|
||||||
</head>
|
</head>
|
||||||
}
|
}
|
||||||
|
|
6
test/fixtures/basic/pages/styled-jsx.js
vendored
Normal file
6
test/fixtures/basic/pages/styled-jsx.js
vendored
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
export default () => (
|
||||||
|
<div>
|
||||||
|
<p>This is blue</p>
|
||||||
|
<style jsx>{`p { color: blue }`}</style>
|
||||||
|
</div>
|
||||||
|
)
|
|
@ -45,6 +45,12 @@ describe('integration tests', () => {
|
||||||
expect(/<div class="css-\w+">This is red<\/div>/.test(html)).toBeTruthy()
|
expect(/<div class="css-\w+">This is red<\/div>/.test(html)).toBeTruthy()
|
||||||
})
|
})
|
||||||
|
|
||||||
|
test('renders styled jsx', async () => {
|
||||||
|
const html = await render('/styled-jsx')
|
||||||
|
expect(html).toMatch(/<style id="__jsx-style-1401785258">p\[data-jsx="1401785258"] {color: blue }[^]+<\/style>/)
|
||||||
|
expect(html.includes('<div data-jsx="1401785258"><p data-jsx="1401785258">This is blue</p></div>')).toBeTruthy()
|
||||||
|
})
|
||||||
|
|
||||||
test('renders properties populated asynchronously', async () => {
|
test('renders properties populated asynchronously', async () => {
|
||||||
const html = await render('/async-props')
|
const html = await render('/async-props')
|
||||||
expect(html.includes('<p>Diego Milito</p>')).toBeTruthy()
|
expect(html.includes('<p>Diego Milito</p>')).toBeTruthy()
|
||||||
|
@ -62,8 +68,8 @@ describe('integration tests', () => {
|
||||||
|
|
||||||
test('error 404', async () => {
|
test('error 404', async () => {
|
||||||
const html = await render('/non-existent')
|
const html = await render('/non-existent')
|
||||||
expect(html).toMatch(/<h1 class=".+">404<\/h1>/)
|
expect(html).toMatch(/<h1 data-jsx=".+">404<\/h1>/)
|
||||||
expect(html).toMatch(/<h2 class=".+">This page could not be found\.<\/h2>/)
|
expect(html).toMatch(/<h2 data-jsx=".+">This page could not be found\.<\/h2>/)
|
||||||
})
|
})
|
||||||
|
|
||||||
test('finishes response', async () => {
|
test('finishes response', async () => {
|
||||||
|
|
Loading…
Reference in a new issue