1
0
mirror of synced 2025-12-19 18:11:23 -05:00

add first blitz integration test for useQuery (#2193)

* add first blitz integration test for useQuery

* link to couple nextjs test files instead of duplicate

* CI name tweaks (meta)
This commit is contained in:
Brandon Bayer
2021-04-08 18:23:19 -04:00
committed by GitHub
parent bc0c7287ec
commit fa8fd64921
22 changed files with 130 additions and 232 deletions

View File

@@ -91,6 +91,7 @@ module.exports = {
rules: {
"import/no-default-export": "off",
"require-await": "off",
"unicorn/filename-case": "off",
},
},
],

View File

@@ -90,7 +90,7 @@ jobs:
key: ${{ github.sha }}
testBlitzPackages:
name: Blitz Packages Tests
name: Blitz - Test Packages
needs: build
runs-on: ubuntu-latest
steps:
@@ -110,7 +110,7 @@ jobs:
testBlitzExamples:
timeout-minutes: 30
name: Blitz Example Apps Tests
name: Blitz - Test Example Apps
strategy:
matrix:
os: [ubuntu-latest, windows-latest]

View File

@@ -34,7 +34,6 @@ module.exports = {
"@babel/preset-env",
{
modules: false,
// loose: true,
exclude: [
"@babel/plugin-transform-async-to-generator",
"@babel/plugin-transform-regenerator",
@@ -45,5 +44,21 @@ module.exports = {
],
plugins: [],
},
{
test: "./nextjs/test/**/*",
presets: [
[
"@babel/preset-env",
{
modules: false,
exclude: [
"@babel/plugin-transform-async-to-generator",
"@babel/plugin-transform-regenerator",
],
},
],
"blitz/babel",
],
},
],
}

View File

@@ -3,6 +3,9 @@ module.exports = {
verbose: true,
rootDir: "test",
modulePaths: ["<rootDir>/lib"],
moduleNameMapper: {
"^lib/(.+)$": "<rootDir>/lib/$1",
},
globalSetup: "<rootDir>/jest-global-setup.js",
globalTeardown: "<rootDir>/jest-global-teardown.js",
setupFilesAfterEnv: ["<rootDir>/jest-setup-after-env.js"],

View File

@@ -10,7 +10,7 @@ interface Chain {
hasElementByCssSelector: () => Chain
click: () => Chain
elementsByCss: () => Chain
waitForElementByCss: () => Chain
waitForElementByCss: (arg: string) => Chain
eval: () => Chain
log: () => Chain
url: () => Chain

View File

@@ -1,13 +1,13 @@
/// <reference types="./next-webdriver" />
import fetch from 'node-fetch'
import os from 'os'
import path from 'path'
import fetch from 'node-fetch'
import Chain from './wd-chain'
import { Builder, By } from 'selenium-webdriver'
import { Options as ChromeOptions } from 'selenium-webdriver/chrome'
import { Options as SafariOptions } from 'selenium-webdriver/safari'
import { Options as FireFoxOptions } from 'selenium-webdriver/firefox'
import { waitFor } from 'next-test-utils'
import { Options as SafariOptions } from 'selenium-webdriver/safari'
import { waitFor } from './next-test-utils'
import Chain from './wd-chain'
const {
BROWSER_NAME: browserName = 'chrome',

View File

@@ -0,0 +1,3 @@
export default async function getBasic() {
return "basic-result"
}

View File

@@ -1,11 +1 @@
module.exports = {
// replace me
async rewrites() {
return [
{
source: "/blog/post/:pid",
destination: "/blog/:pid",
},
]
},
}
module.exports = {}

View File

@@ -0,0 +1,5 @@
import {AppProps} from "blitz"
export default function App({Component, pageProps}: AppProps) {
return <Component {...pageProps} />
}

View File

@@ -0,0 +1,23 @@
import {BlitzScript, Document, DocumentHead, Html, Main} from "blitz"
class MyDocument extends Document {
// Only uncomment if you need to customize this behaviour
// static async getInitialProps(ctx: DocumentContext) {
// const initialProps = await Document.getInitialProps(ctx)
// return {...initialProps}
// }
render() {
return (
<Html lang="en">
<DocumentHead />
<body>
<Main />
<BlitzScript />
</body>
</Html>
)
}
}
export default MyDocument

View File

@@ -1,16 +0,0 @@
import {useRouter} from "blitz"
import React from "react"
const Post = () => {
const router = useRouter()
return (
<>
<div id="as-path">{router.asPath}</div>
</>
)
}
Post.getInitialProps = () => ({hello: "hi"})
export default Post

View File

@@ -1,3 +0,0 @@
const page = () => "hello from sub id"
page.getInitialProps = () => ({hello: "hi"})
export default page

View File

@@ -1 +0,0 @@
export default () => <p id="normal-text">a normal page</p>

View File

@@ -0,0 +1,20 @@
import getBasic from "app/queries/getBasic"
import {useQuery} from "blitz"
import {Suspense} from "react"
function Content() {
const [result] = useQuery(getBasic, null)
return <div id="content">{result}</div>
}
function Page() {
return (
<div id="page">
<Suspense fallback={"Loading..."}>
<Content />
</Suspense>
</div>
)
}
export default Page

View File

@@ -1,81 +1,32 @@
import {
blitzBuild,
blitzStart,
File,
findPort,
killApp,
launchApp,
renderViaHTTP,
} from "blitz-test-utils"
import cheerio from "cheerio"
/* eslint-env jest */
import {findPort, killApp, launchApp, renderViaHTTP} from "lib/blitz-test-utils"
import webdriver from "lib/next-webdriver"
import {join} from "path"
const context: any = {}
jest.setTimeout(1000 * 60 * 5)
let app: any
let appPort: number
const appDir = join(__dirname, "..")
const blitzConfig = new File(join(appDir, "blitz.config.js"))
const runTests = () => {
it("should have gip in __NEXT_DATA__", async () => {
const html = await renderViaHTTP(appPort, "/")
const $ = cheerio.load(html)
expect(JSON.parse($("#__NEXT_DATA__").text()).gip).toBe(true)
})
it("should not have gip in __NEXT_DATA__ for non-GIP page", async () => {
const html = await renderViaHTTP(appPort, "/normal")
const $ = cheerio.load(html)
expect("gip" in JSON.parse($("#__NEXT_DATA__").text())).toBe(false)
})
it("should have correct router.asPath for direct visit dynamic page", async () => {
const html = await renderViaHTTP(appPort, "/blog/1")
const $ = cheerio.load(html)
expect($("#as-path").text()).toBe("/blog/1")
})
it("should have correct router.asPath for direct visit dynamic page rewrite direct", async () => {
const html = await renderViaHTTP(appPort, "/blog/post/1")
const $ = cheerio.load(html)
expect($("#as-path").text()).toBe("/blog/post/1")
})
}
describe("getInitialProps", () => {
describe("dev mode", () => {
beforeAll(async () => {
appPort = await findPort()
app = await launchApp(appDir, appPort)
})
afterAll(() => killApp(app))
runTests()
})
describe("serverless mode", () => {
beforeAll(async () => {
blitzConfig.replace("// replace me", `target: 'serverless', `)
await blitzBuild(appDir)
appPort = await findPort()
app = await blitzStart(appDir, appPort)
})
afterAll(async () => {
await killApp(app)
blitzConfig.restore()
describe("Queries", () => {
beforeAll(async () => {
context.appPort = await findPort()
context.server = await launchApp(join(__dirname, "../"), context.appPort, {
env: {__NEXT_TEST_WITH_DEVTOOL: 1},
})
runTests()
const prerender = ["/use-query"]
await Promise.all(prerender.map((route) => renderViaHTTP(context.appPort, route)))
})
afterAll(() => killApp(context.server))
describe("production mode", () => {
beforeAll(async () => {
await blitzBuild(appDir)
appPort = await findPort()
app = await blitzStart(appDir, appPort)
describe("useQuery", () => {
it("should render query result", async () => {
const browser = await webdriver(context.appPort, "/use-query")
let text = await browser.elementByCss("#page").text()
expect(text).toMatch(/Loading/)
await browser.waitForElementByCss("#content")
text = await browser.elementByCss("#content").text()
if (browser) await browser.close()
expect(text).toMatch(/basic-result/)
})
afterAll(() => killApp(app))
runTests()
})
})

View File

@@ -0,0 +1,25 @@
{
"compilerOptions": {
"target": "es5",
"lib": ["dom", "dom.iterable", "esnext"],
"baseUrl": "./",
"allowJs": true,
"skipLibCheck": true,
"strict": true,
"forceConsistentCasingInFileNames": true,
"noEmit": true,
"esModuleInterop": true,
"module": "esnext",
"moduleResolution": "node",
"resolveJsonModule": true,
"isolatedModules": true,
"jsx": "preserve",
"incremental": true,
"tsBuildInfoFile": ".tsbuildinfo",
"paths": {
"lib/*": ["../../lib/*"]
}
},
"exclude": ["node_modules"],
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"]
}

View File

@@ -1,89 +0,0 @@
// my-custom-environment
const http = require("http")
const getPort = require("get-port")
const seleniumServer = require("selenium-standalone")
const NodeEnvironment = require("jest-environment-node")
const {BROWSER_NAME: browserName = "chrome", SKIP_LOCAL_SELENIUM_SERVER} = process.env
const newTabPg = `
<!DOCTYPE html>
<html>
<head>
<title>new tab</title>
</head>
<body>
<a href="about:blank" target="_blank" id="new">Click me</a>
</body>
</html>
`
class CustomEnvironment extends NodeEnvironment {
async setup() {
await super.setup()
// Since ie11 doesn't like dataURIs we have to spin up a
// server to handle the new tab page
this.server = http.createServer((req, res) => {
res.statusCode = 200
res.end(newTabPg)
})
const newTabPort = await getPort()
await new Promise((resolve, reject) => {
this.server.listen(newTabPort, (err) => {
if (err) return reject(err)
resolve()
})
})
let seleniumServerPort
if (browserName !== "chrome" && SKIP_LOCAL_SELENIUM_SERVER !== "true") {
console.log("Installing selenium server")
await new Promise((resolve, reject) => {
seleniumServer.install((err) => {
if (err) return reject(err)
resolve()
})
})
console.log("Starting selenium server")
await new Promise((resolve, reject) => {
seleniumServer.start((err, child) => {
if (err) return reject(err)
this.seleniumServer = child
resolve()
})
})
console.log("Started selenium server")
seleniumServerPort = 4444
}
this.global.wd = null
this.global._newTabPort = newTabPort
this.global.browserName = browserName
this.global.seleniumServerPort = seleniumServerPort
this.global.browserStackLocalId = global.browserStackLocalId
}
async teardown() {
await super.teardown()
if (this.server) {
this.server.close()
}
if (this.global.wd) {
try {
await this.global.wd.quit()
} catch (err) {
console.log(`Failed to quit webdriver instance`, err)
}
}
// must come after wd.quit()
if (this.seleniumServer) {
this.seleniumServer.kill()
}
}
}
module.exports = CustomEnvironment

1
test/jest-environment.js Symbolic link
View File

@@ -0,0 +1 @@
../nextjs/test/jest-environment.js

View File

@@ -1,24 +0,0 @@
let globalSetup = () => {}
if (process.env.BROWSERSTACK) {
const {Local} = require("browserstack-local")
const browserStackLocal = new Local()
const localBrowserStackOpts = {
key: process.env.BROWSERSTACK_ACCESS_KEY,
localIdentifier: new Date().getTime(), // Adding a unique local identifier to run parallel tests on BrowserStack
}
global.browserStackLocal = browserStackLocal
global.browserStackLocalId = localBrowserStackOpts.localIdentifier
globalSetup = () => {
return new Promise((resolve, reject) => {
browserStackLocal.start(localBrowserStackOpts, (err) => {
if (err) return reject(err)
console.log("Started BrowserStackLocal", browserStackLocal.isRunning())
resolve()
})
})
}
}
module.exports = globalSetup

1
test/jest-global-setup.js Symbolic link
View File

@@ -0,0 +1 @@
../nextjs/test/jest-global-setup.js

View File

@@ -1,9 +0,0 @@
let globalTeardown = () => {}
if (process.env.BROWSERSTACK) {
globalTeardown = () => global.browserStackLocal.killAllProcesses(() => {})
}
module.exports = async () => {
await globalTeardown()
}

View File

@@ -0,0 +1 @@
../nextjs/test/jest-global-teardown.js

1
test/lib/next-webdriver.d.ts vendored Symbolic link
View File

@@ -0,0 +1 @@
../../nextjs/test/lib/next-webdriver.d.ts

1
test/lib/next-webdriver.js Symbolic link
View File

@@ -0,0 +1 @@
../../nextjs/test/lib/next-webdriver.js

View File

@@ -4,7 +4,6 @@
/* "module": "esnext", */
/* "target": "esnext", */
"allowJs": true,
"baseUrl": "./lib",
"resolveJsonModule": true,
"noEmit": true
}