1
0
mirror of synced 2025-12-19 09:57:42 -05:00

Use vitest instead of jest (#50150)

This commit is contained in:
Peter Bengtsson
2024-04-16 13:07:22 -04:00
committed by GitHub
parent e53e71820d
commit e0c8c80982
167 changed files with 1876 additions and 351 deletions

View File

@@ -2,7 +2,7 @@ name: Headless Tests
# **What it does**: This runs our browser tests to test things that depend
# on client-side JavaScript.
# **Why we have it**: Because most automated jest tests only test static
# **Why we have it**: Because most automated vitest tests only test static
# input and outputs.
# **Who does it impact**: Docs engineering, open-source engineering contributors.

View File

@@ -19,7 +19,7 @@ concurrency:
cancel-in-progress: true
env:
# Setting this will activate the jest tests that depend on actually
# Setting this will activate the vitest tests that depend on actually
# sending real search queries to Elasticsearch
ELASTICSEARCH_URL: http://localhost:9200/

1330
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -35,7 +35,7 @@
"index-test-fixtures": "npm run index-elasticsearch -- -l en -l ja -V ghec -V dotcom --index-prefix tests -- src/search/tests/fixtures/search-indexes",
"lint": "eslint '**/*.{js,mjs,ts,tsx}'",
"lint-content": "node src/content-linter/scripts/lint-content.js",
"lint-translation": "cross-env NODE_OPTIONS=--experimental-vm-modules jest src/content-linter/tests/lint-files.js",
"lint-translation": "cross-env NODE_OPTIONS=--experimental-vm-modules vitest src/content-linter/tests/lint-files.js",
"generate-code-scanning-query-list": "tsx src/code-scanning/scripts/generate-code-scanning-query-list.ts",
"generate-content-linter-docs": "tsx src/content-linter/scripts/generate-docs.ts",
"move-content": "node src/content-render/scripts/move-content.js",
@@ -63,10 +63,9 @@
"sync-search-indices": "node src/search/scripts/sync-search-indices.js",
"sync-search-server": "cross-env NODE_ENV=production PORT=4002 MINIMAL_RENDER=true CHANGELOG_DISABLED=true tsx src/frame/server.ts",
"sync-webhooks": "src/rest/scripts/update-files.js -o webhooks",
"test": "cross-env NODE_OPTIONS='--max_old_space_size=4096 --experimental-vm-modules' jest --logHeapUsage",
"test": "cross-env NODE_OPTIONS='--max_old_space_size=4096 --experimental-vm-modules' vitest",
"test-local-dev": "node src/workflows/test-local-dev.js",
"test-moved-content": "tsx src/content-render/scripts/test-moved-content.ts",
"test-watch": "cross-env NODE_OPTIONS=--experimental-vm-modules jest --watch --notify --notifyMode=change --coverage",
"tsc": "tsc --noEmit",
"unallowed-contributions": "node src/workflows/unallowed-contributions.js",
"update-data-and-image-paths": "node src/early-access/scripts/update-data-and-image-paths.js",
@@ -153,14 +152,6 @@
]
},
"overrides": [
{
"files": [
"**/tests/**/*.js"
],
"env": {
"jest": true
}
},
{
"files": [
"**/*.tsx",
@@ -197,41 +188,6 @@
"src/code-scanning/scripts/generate-code-scanning-query-list.ts"
]
},
"jest": {
"testTimeout": 30000,
"coverageThreshold": {
"global": {
"branches": 95,
"functions": 95,
"lines": 95,
"statements": -5
}
},
"globalSetup": "./src/tests/scripts/start-server-for-jest.js",
"globalTeardown": "./src/tests/scripts/kill-server-for-jest.js",
"moduleNameMapper": {
"@primer/behaviors": "<rootDir>/node_modules/@primer/behaviors/dist/cjs/index.js"
},
"preset": "ts-jest",
"reporters": [
"default",
"github-actions"
],
"setupFilesAfterEnv": [
"./src/tests/jest.setup.js",
"jest-expect-message"
],
"testEnvironment": "node",
"testMatch": [
"**/tests/**/*.js"
],
"testPathIgnorePatterns": [
"node_modules/",
"vendor/",
"src/fixtures/fixtures/",
"src/tests/helpers/"
]
},
"dependencies": {
"@elastic/elasticsearch": "8.11.0",
"@github/failbot": "0.8.3",
@@ -383,6 +339,7 @@
"typescript": "^5.4.4",
"unist-util-remove": "^4.0.0",
"unist-util-visit-parents": "6.0.1",
"vitest": "1.5.0",
"website-scraper": "^5.3.1"
},
"overrides": {

View File

@@ -1,11 +1,11 @@
import { describe, jest, test } from '@jest/globals'
import { describe, expect, test, vi } from 'vitest'
import enterpriseServerReleases from '#src/versions/lib/enterprise-server-releases.js'
import { get, getDOM } from '#src/tests/helpers/e2etest.js'
import { SURROGATE_ENUMS } from '#src/frame/middleware/set-fastly-surrogate-key.js'
describe('enterprise deprecation', () => {
jest.setTimeout(60 * 1000)
vi.setConfig({ testTimeout: 60 * 1000 })
test('redirects language-prefixed requests for deprecated enterprise content', async () => {
const res = await get('/en/enterprise/2.12')

View File

@@ -1,4 +1,5 @@
import { jest } from '@jest/globals'
import { describe, expect, test, vi } from 'vitest'
import sharp from 'sharp'
import { fileTypeFromBuffer } from 'file-type'
@@ -6,7 +7,7 @@ import { SURROGATE_ENUMS } from '#src/frame/middleware/set-fastly-surrogate-key.
import { get, head } from '#src/tests/helpers/e2etest.js'
describe('dynamic assets', () => {
jest.setTimeout(3 * 60 * 1000)
vi.setConfig({ testTimeout: 3 * 60 * 1000 })
test('GET PNG as a WebP', async () => {
const res = await get('/assets/images/_fixtures/screenshot.webp', {

View File

@@ -1,5 +1,5 @@
import { afterAll, beforeAll, describe, expect, test, vi } from 'vitest'
import nock from 'nock'
import { expect, jest } from '@jest/globals'
import { checkCachingHeaders } from '#src/tests/helpers/caching-headers.js'
import { setDefaultFastlySurrogateKey } from '#src/frame/middleware/set-fastly-surrogate-key.js'
@@ -57,7 +57,7 @@ describe('archived enterprise static assets', () => {
// Sometimes static assets are proxied. The URL for the static asset
// might not indicate it's based on archived enterprise version.
jest.setTimeout(60 * 1000)
vi.setConfig({ testTimeout: 60 * 1000 })
beforeAll(async () => {
// The first page load takes a long time so let's get it out of the way in

View File

@@ -1,7 +1,7 @@
import fs from 'fs'
import path from 'path'
import { jest, expect } from '@jest/globals'
import { describe, expect, test, vi } from 'vitest'
import { get } from '#src/tests/helpers/e2etest.js'
import { checkCachingHeaders } from '#src/tests/helpers/caching-headers.js'
@@ -14,7 +14,7 @@ function getNextStaticAsset(directory) {
}
describe('static assets', () => {
jest.setTimeout(60 * 1000)
vi.setConfig({ testTimeout: 60 * 1000 })
test('should serve /assets/cb-* with optimal headers', async () => {
const res = await get('/assets/cb-1234/images/site/logo.png')

View File

@@ -1,4 +1,4 @@
import { expect } from '@jest/globals'
import { describe, expect, test } from 'vitest'
import { getDOM } from '#src/tests/helpers/e2etest.js'
import { allVersions } from '#src/versions/lib/all-versions.js'

View File

@@ -1,3 +1,5 @@
import { describe, expect, test } from 'vitest'
import {
filterByAllowlistValues,
filterAndUpdateGhesDataByAllowlistValues,

View File

@@ -1,4 +1,4 @@
import { describe, expect } from '@jest/globals'
import { describe, expect, test } from 'vitest'
import { supported } from '#src/versions/lib/enterprise-server-releases.js'
import { allVersionKeys, allVersions } from '#src/versions/lib/all-versions.js'

View File

@@ -1,7 +1,7 @@
import { readFileSync } from 'fs'
import cheerio from 'cheerio'
import { jest, test } from '@jest/globals'
import { describe, expect, test, vi } from 'vitest'
import { loadPages } from '#src/frame/lib/page-data.js'
import { get } from '#src/tests/helpers/e2etest.js'
@@ -10,7 +10,7 @@ import { get } from '#src/tests/helpers/e2etest.js'
const pageList = await loadPages(undefined, ['en'])
describe('autogenerated docs render', () => {
jest.setTimeout(3 * 60 * 1000)
vi.setConfig({ testTimeout: 3 * 60 * 1000 })
const autogeneratedPages = pageList.filter((page) => page.autogenerated)

View File

@@ -1,9 +1,10 @@
import { expect } from '@jest/globals'
import { tmpdir } from 'os'
import { mkdirp } from 'mkdirp'
import { cp, rm, readFile } from 'fs/promises'
import { existsSync } from 'fs'
import path from 'path'
import { afterAll, beforeAll, describe, expect, test } from 'vitest'
import { mkdirp } from 'mkdirp'
import matter from 'gray-matter'
import { updateContentDirectory } from '../lib/update-markdown.js'

View File

@@ -2,6 +2,7 @@ import fs from 'fs/promises'
import path from 'path'
import nock from 'nock'
import { afterAll, beforeAll, describe, expect, test } from 'vitest'
import { getChangelogItems } from '#src/changelogs/lib/changelog.js'

View File

@@ -1,4 +1,5 @@
import { describe, expect, test } from '@jest/globals'
import { describe, expect, test } from 'vitest'
import {
getComponentTheme,
getCssTheme,

View File

@@ -1,9 +1,11 @@
import path from 'path'
import fs from 'fs'
import walk from 'walk-sync'
import { zip, difference } from 'lodash-es'
import GithubSlugger from 'github-slugger'
import { decode } from 'html-entities'
import { beforeAll, describe, expect, test } from 'vitest'
import matter from '#src/frame/lib/read-frontmatter.js'
import { renderContent } from '#src/content-render/index.js'
@@ -33,10 +35,13 @@ describe('category pages', () => {
const productIndices = walk(contentDir, walkOptions)
const productNames = productIndices.map((index) => path.basename(path.dirname(index)))
// Combine those to fit Jest's `.each` usage
// Combine those to fit vitest's `.each` usage
const productTuples = zip(productNames, productIndices)
describe.each(productTuples)('product "%s"', (productName, productIndex) => {
// Use a regular forEach loop to generate the `describe(...)` blocks
// otherwise, if one of them has no categories, the tests will fail.
productTuples.forEach((tuple) => {
const [, productIndex] = tuple
// Get links included in product index page.
// Each link corresponds to a product subdirectory (category).
// Example: "getting-started-with-github"
@@ -48,7 +53,7 @@ describe('category pages', () => {
const categoryLinks = data.children
// Only include category directories, not standalone category files like content/actions/quickstart.md
.filter((link) => fs.existsSync(getPath(productDir, link, 'index')))
// TODO this should move to async, but you can't asynchronously define tests with Jest...
// TODO this should move to async, but you can't asynchronously define tests with vitest...
// Map those to the Markdown file paths that represent that category page index
const categoryPaths = categoryLinks.map((link) => getPath(productDir, link, 'index'))
@@ -56,11 +61,9 @@ describe('category pages', () => {
// Make them relative for nicer display in test names
const categoryRelativePaths = categoryPaths.map((p) => path.relative(contentDir, p))
// Combine those to fit Jest's `.each` usage
// Combine those to fit vitests's `.each` usage
const categoryTuples = zip(categoryRelativePaths, categoryPaths, categoryLinks)
if (!categoryTuples.length) return
describe.each(categoryTuples)(
'category index "%s"',
(indexRelPath, indexAbsPath, indexLink) => {

View File

@@ -1,6 +1,8 @@
import yaml from 'js-yaml'
import { readFile } from 'fs/promises'
import walk from 'walk-sync'
import { beforeAll, describe, expect, test } from 'vitest'
import { liquid } from '#src/content-render/index.js'

View File

@@ -1,10 +1,12 @@
import { fileURLToPath } from 'url'
import path from 'path'
import yaml from 'js-yaml'
import fs from 'fs/promises'
import slash from 'slash'
import walk from 'walk-sync'
import { zip } from 'lodash-es'
import yaml from 'js-yaml'
import fs from 'fs/promises'
import { beforeAll, describe, expect, test } from 'vitest'
import languages from '#src/languages/lib/languages.js'
import { getDiffFiles } from '../lib/diff-files.js'
@@ -235,198 +237,198 @@ if (ymlToLint.length === 0) {
describe('deliberately do nothing', () => {
test('void', () => {})
})
}
} else {
describe('lint yaml content', () => {
if (ymlToLint.length < 1) return
describe.each(ymlToLint)('%s', (yamlRelPath, yamlAbsPath) => {
let dictionary, isEarlyAccess, fileContents
// This variable is used to determine if the file was parsed successfully.
// When `yaml.load()` fails to parse the file, it is overwritten with the error message.
// `false` is intentionally chosen since `null` and `undefined` are valid return values.
let dictionaryError = false
describe('lint yaml content', () => {
if (ymlToLint.length < 1) return
describe.each(ymlToLint)('%s', (yamlRelPath, yamlAbsPath) => {
let dictionary, isEarlyAccess, fileContents
// This variable is used to determine if the file was parsed successfully.
// When `yaml.load()` fails to parse the file, it is overwritten with the error message.
// `false` is intentionally chosen since `null` and `undefined` are valid return values.
let dictionaryError = false
beforeAll(async () => {
fileContents = await fs.readFile(yamlAbsPath, 'utf8')
try {
dictionary = yaml.load(fileContents, { filename: yamlRelPath })
} catch (error) {
dictionaryError = error
}
beforeAll(async () => {
fileContents = await fs.readFile(yamlAbsPath, 'utf8')
try {
dictionary = yaml.load(fileContents, { filename: yamlRelPath })
} catch (error) {
dictionaryError = error
}
isEarlyAccess = yamlRelPath.split('/').includes('early-access')
})
isEarlyAccess = yamlRelPath.split('/').includes('early-access')
})
test('it can be parsed as a single yaml document', () => {
expect(dictionaryError).toBe(false)
})
test('it can be parsed as a single yaml document', () => {
expect(dictionaryError).toBe(false)
})
test('placeholder string is not present in any yaml files', () => {
const matches = fileContents.match(placeholderRegex) || []
const errorMessage = `
test('placeholder string is not present in any yaml files', () => {
const matches = fileContents.match(placeholderRegex) || []
const errorMessage = `
Found ${matches.length} placeholder string '${placeholder}'! Please update all placeholders.
`
expect(matches.length, errorMessage).toBe(0)
})
expect(matches.length, errorMessage).toBe(0)
})
test('relative URLs must start with "/"', async () => {
const matches = []
for (const [key, content] of Object.entries(dictionary)) {
const contentStr = getContent(content)
if (!contentStr) continue
const valMatches = contentStr.match(relativeArticleLinkRegex) || []
if (valMatches.length > 0) {
matches.push(...valMatches.map((match) => `Key "${key}": ${match}`))
}
}
const errorMessage = formatLinkError(relativeArticleLinkErrorText, matches)
expect(matches.length, errorMessage).toBe(0)
})
test('must not leak Early Access doc URLs', async () => {
// Only execute for docs that are NOT Early Access
if (!isEarlyAccess) {
test('relative URLs must start with "/"', async () => {
const matches = []
for (const [key, content] of Object.entries(dictionary)) {
const contentStr = getContent(content)
if (!contentStr) continue
const valMatches = contentStr.match(earlyAccessLinkRegex) || []
const valMatches = contentStr.match(relativeArticleLinkRegex) || []
if (valMatches.length > 0) {
matches.push(...valMatches.map((match) => `Key "${key}": ${match}`))
}
}
const errorMessage = formatLinkError(earlyAccessLinkErrorText, matches)
const errorMessage = formatLinkError(relativeArticleLinkErrorText, matches)
expect(matches.length, errorMessage).toBe(0)
}
})
})
test('must not leak Early Access image URLs', async () => {
// Only execute for docs that are NOT Early Access
if (!isEarlyAccess) {
test('must not leak Early Access doc URLs', async () => {
// Only execute for docs that are NOT Early Access
if (!isEarlyAccess) {
const matches = []
for (const [key, content] of Object.entries(dictionary)) {
const contentStr = getContent(content)
if (!contentStr) continue
const valMatches = contentStr.match(earlyAccessLinkRegex) || []
if (valMatches.length > 0) {
matches.push(...valMatches.map((match) => `Key "${key}": ${match}`))
}
}
const errorMessage = formatLinkError(earlyAccessLinkErrorText, matches)
expect(matches.length, errorMessage).toBe(0)
}
})
test('must not leak Early Access image URLs', async () => {
// Only execute for docs that are NOT Early Access
if (!isEarlyAccess) {
const matches = []
for (const [key, content] of Object.entries(dictionary)) {
const contentStr = getContent(content)
if (!contentStr) continue
const valMatches = contentStr.match(earlyAccessImageRegex) || []
if (valMatches.length > 0) {
matches.push(...valMatches.map((match) => `Key "${key}": ${match}`))
}
}
const errorMessage = formatLinkError(earlyAccessImageErrorText, matches)
expect(matches.length, errorMessage).toBe(0)
}
})
test('must have correctly formatted Early Access image URLs', async () => {
// Execute for ALL docs (not just Early Access) to ensure non-EA docs
// are not leaking incorrectly formatted EA image URLs
const matches = []
for (const [key, content] of Object.entries(dictionary)) {
const contentStr = getContent(content)
if (!contentStr) continue
const valMatches = contentStr.match(earlyAccessImageRegex) || []
const valMatches = contentStr.match(badEarlyAccessImageRegex) || []
if (valMatches.length > 0) {
matches.push(...valMatches.map((match) => `Key "${key}": ${match}`))
}
}
const errorMessage = formatLinkError(earlyAccessImageErrorText, matches)
const errorMessage = formatLinkError(badEarlyAccessImageErrorText, matches)
expect(matches.length, errorMessage).toBe(0)
}
})
})
test('must have correctly formatted Early Access image URLs', async () => {
// Execute for ALL docs (not just Early Access) to ensure non-EA docs
// are not leaking incorrectly formatted EA image URLs
const matches = []
test('URLs must not contain a hard-coded language code', async () => {
const matches = []
for (const [key, content] of Object.entries(dictionary)) {
const contentStr = getContent(content)
if (!contentStr) continue
const valMatches = contentStr.match(badEarlyAccessImageRegex) || []
if (valMatches.length > 0) {
matches.push(...valMatches.map((match) => `Key "${key}": ${match}`))
for (const [key, content] of Object.entries(dictionary)) {
const contentStr = getContent(content)
if (!contentStr) continue
const valMatches = contentStr.match(languageLinkRegex) || []
if (valMatches.length > 0) {
matches.push(...valMatches.map((match) => `Key "${key}": ${match}`))
}
}
}
const errorMessage = formatLinkError(badEarlyAccessImageErrorText, matches)
expect(matches.length, errorMessage).toBe(0)
})
const errorMessage = formatLinkError(languageLinkErrorText, matches)
expect(matches.length, errorMessage).toBe(0)
})
test('URLs must not contain a hard-coded language code', async () => {
const matches = []
test('URLs must not contain a hard-coded version number', async () => {
const matches = []
for (const [key, content] of Object.entries(dictionary)) {
const contentStr = getContent(content)
if (!contentStr) continue
const valMatches = contentStr.match(languageLinkRegex) || []
if (valMatches.length > 0) {
matches.push(...valMatches.map((match) => `Key "${key}": ${match}`))
for (const [key, content] of Object.entries(dictionary)) {
const contentStr = getContent(content)
if (!contentStr) continue
const valMatches = contentStr.match(versionLinkRegEx) || []
if (valMatches.length > 0) {
matches.push(...valMatches.map((match) => `Key "${key}": ${match}`))
}
}
}
const errorMessage = formatLinkError(languageLinkErrorText, matches)
expect(matches.length, errorMessage).toBe(0)
})
const errorMessage = formatLinkError(versionLinkErrorText, matches)
expect(matches.length, errorMessage).toBe(0)
})
test('URLs must not contain a hard-coded version number', async () => {
const matches = []
test('URLs must not contain a hard-coded domain name', async () => {
const matches = []
for (const [key, content] of Object.entries(dictionary)) {
const contentStr = getContent(content)
if (!contentStr) continue
const valMatches = contentStr.match(versionLinkRegEx) || []
if (valMatches.length > 0) {
matches.push(...valMatches.map((match) => `Key "${key}": ${match}`))
for (const [key, content] of Object.entries(dictionary)) {
const contentStr = getContent(content)
if (!contentStr) continue
const valMatches = contentStr.match(domainLinkRegex) || []
if (valMatches.length > 0) {
matches.push(...valMatches.map((match) => `Key "${key}": ${match}`))
}
}
}
const errorMessage = formatLinkError(versionLinkErrorText, matches)
expect(matches.length, errorMessage).toBe(0)
})
const errorMessage = formatLinkError(domainLinkErrorText, matches)
expect(matches.length, errorMessage).toBe(0)
})
test('URLs must not contain a hard-coded domain name', async () => {
const matches = []
test('does not use old site.data variable syntax', async () => {
const matches = []
for (const [key, content] of Object.entries(dictionary)) {
const contentStr = getContent(content)
if (!contentStr) continue
const valMatches = contentStr.match(domainLinkRegex) || []
if (valMatches.length > 0) {
matches.push(...valMatches.map((match) => `Key "${key}": ${match}`))
for (const [key, content] of Object.entries(dictionary)) {
const contentStr = getContent(content)
if (!contentStr) continue
const valMatches = contentStr.match(oldVariableRegex) || []
if (valMatches.length > 0) {
matches.push(
...valMatches.map((match) => {
const example = match.replace(
/{{\s*?site\.data\.([a-zA-Z0-9-_]+(?:\.[a-zA-Z0-9-_]+)+)\s*?}}/g,
'{% data $1 %}',
)
return `Key "${key}": ${match} => ${example}`
}),
)
}
}
}
const errorMessage = formatLinkError(domainLinkErrorText, matches)
expect(matches.length, errorMessage).toBe(0)
})
const errorMessage = formatLinkError(oldVariableErrorText, matches)
expect(matches.length, errorMessage).toBe(0)
})
test('does not use old site.data variable syntax', async () => {
const matches = []
test('does not use old octicon variable syntax', async () => {
const matches = []
for (const [key, content] of Object.entries(dictionary)) {
const contentStr = getContent(content)
if (!contentStr) continue
const valMatches = contentStr.match(oldVariableRegex) || []
if (valMatches.length > 0) {
matches.push(
...valMatches.map((match) => {
const example = match.replace(
/{{\s*?site\.data\.([a-zA-Z0-9-_]+(?:\.[a-zA-Z0-9-_]+)+)\s*?}}/g,
'{% data $1 %}',
)
return `Key "${key}": ${match} => ${example}`
}),
)
for (const [key, content] of Object.entries(dictionary)) {
const contentStr = getContent(content)
if (!contentStr) continue
const valMatches = contentStr.match(oldOcticonRegex) || []
if (valMatches.length > 0) {
matches.push(...valMatches.map((match) => `Key "${key}": ${match}`))
}
}
}
const errorMessage = formatLinkError(oldVariableErrorText, matches)
expect(matches.length, errorMessage).toBe(0)
})
test('does not use old octicon variable syntax', async () => {
const matches = []
for (const [key, content] of Object.entries(dictionary)) {
const contentStr = getContent(content)
if (!contentStr) continue
const valMatches = contentStr.match(oldOcticonRegex) || []
if (valMatches.length > 0) {
matches.push(...valMatches.map((match) => `Key "${key}": ${match}`))
}
}
const errorMessage = formatLinkError(oldOcticonErrorText, matches)
expect(matches.length, errorMessage).toBe(0)
const errorMessage = formatLinkError(oldOcticonErrorText, matches)
expect(matches.length, errorMessage).toBe(0)
})
})
})
})
}

View File

@@ -1,3 +1,5 @@
import { describe, expect, test } from 'vitest'
import { loadPages, loadPageMap } from '#src/frame/lib/page-data.js'
import loadRedirects from '#src/redirects/lib/precompile.js'
import { checkURL } from '#src/tests/helpers/check-url.js'

View File

@@ -1,6 +1,6 @@
import path from 'path'
import { isEqual, uniqWith } from 'lodash-es'
import { jest } from '@jest/globals'
import { describe, expect, test, vi } from 'vitest'
import patterns from '#src/frame/lib/patterns.js'
import { getDataByLanguage, getDeepDataByLanguage } from '#src/data-directory/lib/get-data.js'
@@ -30,7 +30,7 @@ const getDataReferences = (content) => {
}
describe('data references', () => {
jest.setTimeout(60 * 1000)
vi.setConfig({ testTimeout: 60 * 1000 })
test('every data reference found in English variable files is defined and has a value', async () => {
let errors = []

View File

@@ -1,3 +1,5 @@
import { describe, expect, test } from 'vitest'
import { runRule } from '../../lib/init-test.js'
import { codeAnnotations } from '../../lib/linting-rules/code-annotations.js'

View File

@@ -1,3 +1,5 @@
import { describe, expect, test } from 'vitest'
import { runRule } from '../../lib/init-test.js'
import { codeFenceLineLength } from '../../lib/linting-rules/code-fence-line-length.js'

View File

@@ -1,3 +1,5 @@
import { describe, expect, test } from 'vitest'
import { runRule } from '../../lib/init-test.js'
import {
earlyAccessReferences,

View File

@@ -1,3 +1,5 @@
import { describe, expect, test } from 'vitest'
import { runRule } from '../../lib/init-test.js'
import {
expiredContent,

View File

@@ -1,4 +1,4 @@
import { expect } from '@jest/globals'
import { describe, expect, test } from 'vitest'
import { runRule } from '../../lib/init-test.js'
import { frontmatterHiddenDocs } from '../../lib/linting-rules/frontmatter-hidden-docs.js'

View File

@@ -1,3 +1,5 @@
import { describe, expect, test } from 'vitest'
import { runRule } from '../../lib/init-test.js'
import { frontmatterSchema } from '../../lib/linting-rules/frontmatter-schema.js'

View File

@@ -1,4 +1,4 @@
import { expect } from '@jest/globals'
import { describe, expect, test } from 'vitest'
import { runRule } from '../../lib/init-test.js'
import { frontmatterVideoTranscripts } from '../../lib/linting-rules/frontmatter-video-transcripts.js'

View File

@@ -1,3 +1,5 @@
import { describe, expect, test } from 'vitest'
import { runRule } from '../../lib/init-test.js'
import { githubOwnedActionReferences } from '../../lib/linting-rules/github-owned-action-references.js'

View File

@@ -1,3 +1,5 @@
import { describe, expect, test } from 'vitest'
import { runRule } from '../../lib/init-test.js'
import { hardcodedDataVariable } from '../../lib/linting-rules/hardcoded-data-variable.js'

View File

@@ -1,3 +1,5 @@
import { describe, expect, test } from 'vitest'
import { runRule } from '../../lib/init-test.js'
import { imageAltTextEndPunctuation } from '../../lib/linting-rules/image-alt-text-end-punctuation.js'

View File

@@ -1,3 +1,5 @@
import { describe, expect, test } from 'vitest'
import { runRule } from '../../lib/init-test.js'
import { imageAltTextExcludeStartWords } from '../../lib/linting-rules/image-alt-text-exclude-start-words.js'

View File

@@ -1,3 +1,5 @@
import { describe, expect, test } from 'vitest'
import { runRule } from '../../lib/init-test.js'
import { incorrectAltTextLength } from '../../lib/linting-rules/image-alt-text-length.js'

View File

@@ -1,3 +1,5 @@
import { describe, expect, test } from 'vitest'
import { runRule } from '../../lib/init-test.js'
import { imageFileKebabCase } from '../../lib/linting-rules/image-file-kebab-case.js'

View File

@@ -1,3 +1,5 @@
import { describe, expect, test } from 'vitest'
import { runRule } from '../../lib/init-test.js'
import { imageNoGif } from '../../lib/linting-rules/image-no-gif.js'

View File

@@ -1,3 +1,5 @@
import { describe, expect, test } from 'vitest'
import { runRule } from '../../lib/init-test.js'
import { internalLinksNoLang } from '../../lib/linting-rules/internal-links-no-lang.js'

View File

@@ -1,3 +1,5 @@
import { describe, expect, test } from 'vitest'
import { runRule } from '../../lib/init-test.js'
import { internalLinksOldVersion } from '../../lib/linting-rules/internal-links-old-version.js'

View File

@@ -1,3 +1,5 @@
import { describe, expect, test } from 'vitest'
import { runRule } from '../../lib/init-test.js'
import { internalLinksSlash } from '../../lib/linting-rules/internal-links-slash.js'

View File

@@ -1,3 +1,5 @@
import { describe, expect, test } from 'vitest'
import { runRule } from '../../lib/init-test.js'
import { linkPunctuation } from '../../lib/linting-rules/link-punctuation.js'

View File

@@ -1,5 +1,7 @@
import path from 'path'
import { afterAll, beforeAll, describe, expect, test } from 'vitest'
import { runRule } from '../../lib/init-test.js'
import {
liquidDataReferencesDefined,

View File

@@ -1,3 +1,5 @@
import { afterAll, beforeAll, describe, expect, test } from 'vitest'
import { runRule } from '../../lib/init-test.js'
import {
liquidIfVersionVersions,

View File

@@ -1,3 +1,5 @@
import { describe, expect, test } from 'vitest'
import { runRule } from '../../lib/init-test.js'
import { liquidQuotedConditionalArg } from '../../lib/linting-rules/liquid-quoted-conditional-arg.js'

View File

@@ -1,3 +1,5 @@
import { describe, expect, test } from 'vitest'
import { runRule } from '../../lib/init-test.js'
import { frontmatterLiquidSyntax, liquidSyntax } from '../../lib/linting-rules/liquid-syntax.js'

View File

@@ -1,5 +1,7 @@
import path from 'path'
import { afterAll, beforeAll, describe, expect, test } from 'vitest'
import { runRule } from '../../lib/init-test.js'
import { liquidIfTags, liquidIfVersionTags } from '../../lib/linting-rules/liquid-versioning.js'
import { nextNext } from '#src/versions/lib/enterprise-server-releases.js'

View File

@@ -1,3 +1,5 @@
import { describe, expect, test } from 'vitest'
import { runRule } from '../../lib/init-test.js'
import { listFirstWordCapitalization } from '../../lib/linting-rules/list-first-word-capitalization.js'

View File

@@ -1,3 +1,5 @@
import { afterAll, beforeAll, describe, expect, test } from 'vitest'
import { runRule } from '../../lib/init-test.js'
import { raiReusableUsage } from '../../lib/linting-rules/rai-reusable-usage.js'

View File

@@ -1,3 +1,4 @@
import { describe, expect, test } from 'vitest'
import searchReplace from 'markdownlint-rule-search-replace'
import { runRule } from '../../lib/init-test.js'

View File

@@ -1,3 +1,5 @@
import { describe, expect, test } from 'vitest'
import { runRule } from '../../lib/init-test.js'
import { yamlScheduledJobs } from '../../lib/linting-rules/yaml-scheduled-jobs.js'

View File

@@ -1,4 +1,27 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
exports[`annotate > renders annotations 1`] = `
"<div class="annotate beside"><div class="annotate-header"><header class="d-flex flex-items-center flex-justify-between p-2 text-small rounded-top-1 border-top border-left border-right"><span class="flex-1">YAML</span><div class="BtnGroup"><button name="annotate-display" value="beside" type="button" class="BtnGroup-item btn btn-sm">Beside</button><button name="annotate-display" value="inline" type="button" class="BtnGroup-item btn btn-sm">Inline</button></div><button class="js-btn-copy btn btn-sm tooltipped tooltipped-nw" aria-label="Copy YAML code to clipboard" data-clipboard="1746955726" aria-live="polite" aria-atomic="true"><svg version="1.1" width="16" height="16" viewBox="0 0 16 16" class="octicon octicon-copy" aria-hidden="true"><path d="M0 6.75C0 5.784.784 5 1.75 5h1.5a.75.75 0 0 1 0 1.5h-1.5a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-1.5a.75.75 0 0 1 1.5 0v1.5A1.75 1.75 0 0 1 9.25 16h-7.5A1.75 1.75 0 0 1 0 14.25Z"></path><path d="M5 1.75C5 .784 5.784 0 6.75 0h7.5C15.216 0 16 .784 16 1.75v7.5A1.75 1.75 0 0 1 14.25 11h-7.5A1.75 1.75 0 0 1 5 9.25Zm1.75-.25a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-7.5a.25.25 0 0 0-.25-.25Z"></path></svg></button><pre hidden data-clipboard="1746955726"># The name of the workflow as it will appear in the "Actions" tab of the GitHub repository.
name: Post welcome comment
# Add the \`pull_request\` event, so that the workflow runs automatically
# every time a pull request is created.
on:
pull_request:
types: [opened]
</pre></header></div><div class="annotate-beside"><div class="annotate-row"><div class="annotate-code"><pre><code class="hljs language-yaml"><span class="hljs-attr">name:</span> <span class="hljs-string">Post</span> <span class="hljs-string">welcome</span> <span class="hljs-string">comment</span></code></pre></div><div class="annotate-note"><p>The name of the workflow as it will appear in the "Actions" tab of the GitHub repository.</p></div></div><div class="annotate-row"><div class="annotate-code"><pre><code class="hljs language-yaml"><span class="hljs-attr">on:</span>
<span class="hljs-attr">pull_request:</span>
<span class="hljs-attr">types:</span> [<span class="hljs-string">opened</span>]</code></pre></div><div class="annotate-note"><p>Add the <code>pull_request</code> event, so that the workflow runs automatically
every time a pull request is created.</p></div></div></div><div class="annotate-inline"><pre><code class="hljs language-yaml"><span class="hljs-comment"># The name of the workflow as it will appear in the "Actions" tab of the GitHub repository.</span>
<span class="hljs-attr">name:</span> <span class="hljs-string">Post</span> <span class="hljs-string">welcome</span> <span class="hljs-string">comment</span>
<span class="hljs-comment"># Add the \`pull_request\` event, so that the workflow runs automatically</span>
<span class="hljs-comment"># every time a pull request is created.</span>
<span class="hljs-attr">on:</span>
<span class="hljs-attr">pull_request:</span>
<span class="hljs-attr">types:</span> [<span class="hljs-string">opened</span>]
</code></pre></div></div>"
`;
exports[`annotate renders annotations 1`] = `
"<div class="annotate beside"><div class="annotate-header"><header class="d-flex flex-items-center flex-justify-between p-2 text-small rounded-top-1 border-top border-left border-right"><span class="flex-1">YAML</span><div class="BtnGroup"><button name="annotate-display" value="beside" type="button" class="BtnGroup-item btn btn-sm">Beside</button><button name="annotate-display" value="inline" type="button" class="BtnGroup-item btn btn-sm">Inline</button></div><button class="js-btn-copy btn btn-sm tooltipped tooltipped-nw" aria-label="Copy YAML code to clipboard" data-clipboard="1746955726" aria-live="polite" aria-atomic="true"><svg version="1.1" width="16" height="16" viewBox="0 0 16 16" class="octicon octicon-copy" aria-hidden="true"><path d="M0 6.75C0 5.784.784 5 1.75 5h1.5a.75.75 0 0 1 0 1.5h-1.5a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-1.5a.75.75 0 0 1 1.5 0v1.5A1.75 1.75 0 0 1 9.25 16h-7.5A1.75 1.75 0 0 1 0 14.25Z"></path><path d="M5 1.75C5 .784 5.784 0 6.75 0h7.5C15.216 0 16 .784 16 1.75v7.5A1.75 1.75 0 0 1 14.25 11h-7.5A1.75 1.75 0 0 1 5 9.25Zm1.75-.25a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-7.5a.25.25 0 0 0-.25-.25Z"></path></svg></button><pre hidden data-clipboard="1746955726"># The name of the workflow as it will appear in the "Actions" tab of the GitHub repository.

View File

@@ -1,4 +1,6 @@
import { describe, expect, test } from 'vitest'
import cheerio from 'cheerio'
import { renderContent } from '#src/content-render/index.js'
const example = `

View File

@@ -1,4 +1,4 @@
import { afterAll, beforeAll, expect, describe } from '@jest/globals'
import { afterAll, beforeAll, describe, expect, test } from 'vitest'
import Page from '#src/frame/lib/page.js'
import languages from '#src/languages/lib/languages.js'

View File

@@ -1,10 +1,11 @@
import { afterAll, jest, beforeAll, expect } from '@jest/globals'
import { afterAll, beforeAll, describe, expect, test, vi } from 'vitest'
import { liquid } from '#src/content-render/index.js'
import languages from '#src/languages/lib/languages.js'
import { DataDirectory } from '#src/tests/helpers/data-directory.js'
describe('liquid helper tags', () => {
jest.setTimeout(60 * 1000)
vi.setConfig({ testTimeout: 60 * 1000 })
const context = {}
let dd

View File

@@ -1,4 +1,4 @@
import { jest } from '@jest/globals'
import { describe, expect, test, vi } from 'vitest'
import { liquid } from '#src/content-render/index.js'
import shortVersionsMiddleware from '#src/versions/middleware/short-versions.js'
@@ -43,7 +43,7 @@ const contextualize = (req) => {
}
describe('liquid template parser', () => {
jest.setTimeout(60 * 1000)
vi.setConfig({ testTimeout: 60 * 1000 })
describe('short versions', () => {
// Create a fake req so we can test the shortVersions middleware

View File

@@ -1,3 +1,5 @@
import { describe, expect, test } from 'vitest'
import { renderContent } from '#src/content-render/index.js'
describe('octicon tag', () => {

View File

@@ -31,7 +31,7 @@
import path from 'path'
import { jest } from '@jest/globals'
import { describe, expect, test, vi } from 'vitest'
import { head, get } from '#src/tests/helpers/e2etest.js'
import { loadPages } from '#src/frame/lib/page-data.js'
@@ -62,7 +62,7 @@ function getContentFiles(spaceSeparatedList) {
// It can also happen if some of the pages involves are infamously slow.
// For example guide pages because they involved a lot of processing
// to gather and preview linked data.
jest.setTimeout(60 * 1000)
vi.setConfig({ testTimeout: 60 * 1000 })
describe('changed-content', () => {
const changedContentFiles = getChangedContentFiles()

View File

@@ -1,4 +1,6 @@
import cheerio from 'cheerio'
import { describe, expect, test } from 'vitest'
import { renderContent } from '#src/content-render/index.js'
import { EOL } from 'os'

View File

@@ -1,9 +1,10 @@
import { beforeAll } from '@jest/globals'
import yaml from 'js-yaml'
import { readFileSync } from 'fs'
import walk from 'walk-sync'
import { extname, basename } from 'path'
import walk from 'walk-sync'
import { beforeAll, describe, expect, test } from 'vitest'
import { getJsonValidator, validateJson } from '#src/tests/lib/validate-json-schema.js'
import { formatAjvErrors } from '#src/tests/helpers/schemas.js'
import dataSchemas from '#src/data-directory/lib/data-schemas/index.js'

View File

@@ -1,3 +1,5 @@
import { describe, expect, test } from 'vitest'
import filenameToKey from '#src/data-directory/lib/filename-to-key.js'
describe('filename-to-key', () => {

View File

@@ -1,7 +1,7 @@
import fs from 'fs'
import path from 'path'
import { expect, test, describe, beforeAll, afterAll } from '@jest/globals'
import { afterAll, beforeAll, describe, expect, test } from 'vitest'
import languages from '#src/languages/lib/languages.js'
import {
@@ -14,7 +14,7 @@ import { DataDirectory } from '#src/tests/helpers/data-directory.js'
describe('get-data', () => {
let dd
const enDirBefore = languages.en.dir
// Only `en` is available in jest tests, so pretend we also have Japanese
// Only `en` is available in tests, so pretend we also have Japanese
languages.ja = Object.assign({}, languages.en, {})
beforeAll(() => {

View File

@@ -1,6 +1,10 @@
import { fileURLToPath } from 'url'
import path from 'path'
import { describe, expect, test } from 'vitest'
import dataDirectory from '#src/data-directory/lib/data-directory.js'
const __dirname = path.dirname(fileURLToPath(import.meta.url))
const fixturesDir = path.join(__dirname, 'fixtures')

View File

@@ -1,7 +1,7 @@
import { stat } from 'fs/promises'
import path from 'path'
import { expect } from '@jest/globals'
import { describe, expect } from 'vitest'
import { testViaActionsOnly } from '#src/tests/helpers/conditional-runs.js'
import { get, getDOM } from '#src/tests/helpers/e2etest.js'

View File

@@ -1,4 +1,4 @@
import { expect, jest, test } from '@jest/globals'
import { expect, test, vi } from 'vitest'
import { get, getDOM } from '#src/tests/helpers/e2etest.js'
import { describeIfDocsEarlyAccess } from '#src/tests/helpers/conditional-runs.js'
@@ -7,7 +7,7 @@ import languages from '#src/languages/lib/languages.js'
const VALID_EARLY_ACCESS_URI = '/early-access/github/save-time-with-slash-commands'
describeIfDocsEarlyAccess('early access rendering', () => {
jest.setTimeout(60 * 1000)
vi.setConfig({ testTimeout: 60 * 1000 })
test('viewing landing page', async () => {
const res = await get('/en/early-access')

View File

@@ -1,4 +1,5 @@
import { afterEach } from '@jest/globals'
import { afterEach, describe, expect, test } from 'vitest'
import nock from 'nock'
import { publish } from '../lib/hydro.js'

View File

@@ -1,19 +1,20 @@
import { describe, expect, test } from 'vitest'
import { validateJson } from '#src/tests/lib/validate-json-schema.js'
import { formatErrors } from '../lib/middleware-errors.js'
import { schemas } from '../lib/schema.js'
expect.extend({
toMatchSchema(data, schema) {
const { isValid, errors } = validateJson(schema, data)
return {
pass: isValid,
message: () => (isValid ? '' : errors.message),
}
},
})
describe('formatErrors', () => {
test('should produce objects that match the validation spec', () => {
expect.extend({
toMatchSchema(data, schema) {
const { isValid, errors } = validateJson(schema, data)
return {
pass: isValid,
message: () => (isValid ? '' : errors.message),
}
},
})
// Produce an error
const { errors } = validateJson({ type: 'string' }, 0)
const formattedErrors = formatErrors(errors, '')

View File

@@ -1,8 +1,9 @@
import { expect, jest } from '@jest/globals'
import { describe, expect, test, vi } from 'vitest'
import { post } from '#src/tests/helpers/e2etest.js'
describe('POST /events', () => {
jest.setTimeout(60 * 1000)
vi.setConfig({ testTimeout: 60 * 1000 })
async function checkEvent(data) {
const body = JSON.stringify(data)

View File

@@ -1,3 +1,5 @@
import { describe, expect, test } from 'vitest'
import { parseUserAgent } from '../components/user-agent.ts'
describe('parseUserAgent', () => {

View File

@@ -2,13 +2,13 @@
There are currently 3 general automated tests:
1. `jest` tests against real English content (and some code)
1. `jest` tests against fixture content
1. `vitest` tests against real English content (and some code)
1. `vitest` tests against fixture content
1. `playwright` tests against fixture content (What this document is about!)
## Quickstart
Just like with regular `jest` tests, if you haven't already done so...
Just like with regular `vitest` tests, if you haven't already done so...
```shell
npm run build

View File

@@ -1,3 +1,5 @@
import { describe, expect, test } from 'vitest'
import { getDOM } from '#src/tests/helpers/e2etest.js'
describe('annotations', () => {

View File

@@ -1,3 +1,5 @@
import { describe, expect, test } from 'vitest'
import { head } from '#src/tests/helpers/e2etest.js'
describe('bad URLs', () => {

View File

@@ -1,3 +1,5 @@
import { describe, expect, test } from 'vitest'
import { getDOM } from '#src/tests/helpers/e2etest.js'
describe('breadcrumbs', () => {

View File

@@ -1,3 +1,5 @@
import { describe, expect, test } from 'vitest'
import { getDOM, head } from '#src/tests/helpers/e2etest.js'
describe('map topics', () => {

View File

@@ -1,3 +1,5 @@
import { describe, expect, test } from 'vitest'
import { getDOM } from '#src/tests/helpers/e2etest.js'
import nonEnterpriseDefaultVersion from '#src/versions/lib/non-enterprise-default-version.js'

View File

@@ -1,3 +1,5 @@
import { describe, expect, test } from 'vitest'
import { getDOMCached as getDOM } from '#src/tests/helpers/e2etest.js'
describe('glossary', () => {

View File

@@ -1,3 +1,5 @@
import { describe, expect, test } from 'vitest'
import { get, getDOMCached as getDOM } from '#src/tests/helpers/e2etest.js'
describe('guides', () => {

View File

@@ -1,3 +1,5 @@
import { describe, expect, test } from 'vitest'
import { getDOM } from '#src/tests/helpers/e2etest.js'
describe('<head>', () => {

View File

@@ -1,4 +1,4 @@
import { expect } from '@jest/globals'
import { describe, expect, test } from 'vitest'
import { get, getDOM } from '#src/tests/helpers/e2etest.js'

View File

@@ -1,3 +1,4 @@
import { describe, expect, test } from 'vitest'
import sharp from 'sharp'
import { get, head, getDOM } from '#src/tests/helpers/e2etest.js'

View File

@@ -1,3 +1,5 @@
import { describe, expect, test } from 'vitest'
import { get, getDOM } from '#src/tests/helpers/e2etest.js'
import enterpriseServerReleases from '#src/versions/lib/enterprise-server-releases.js'
import { allVersions } from '#src/versions/lib/all-versions.js'

View File

@@ -1,3 +1,5 @@
import { describe, expect, test } from 'vitest'
import { getDOM } from '#src/tests/helpers/e2etest.js'
describe('product landing page', () => {

View File

@@ -1,3 +1,5 @@
import { describe, expect, test } from 'vitest'
import { getDataByLanguage } from '#src/data-directory/lib/get-data.js'
import { getDOM } from '#src/tests/helpers/e2etest.js'
import { supported } from '#src/versions/lib/enterprise-server-releases.js'

View File

@@ -1,3 +1,5 @@
import { describe, expect, test } from 'vitest'
import { getDOM } from '#src/tests/helpers/e2etest.js'
describe('markdown rendering', () => {

View File

@@ -1,4 +1,4 @@
import { describe } from '@jest/globals'
import { describe, expect, test } from 'vitest'
import { getDOM } from '#src/tests/helpers/e2etest.js'

View File

@@ -1,3 +1,5 @@
import { describe, expect, test } from 'vitest'
import enterpriseServerReleases from '#src/versions/lib/enterprise-server-releases.js'
import { getDOM } from '#src/tests/helpers/e2etest.js'

View File

@@ -1,3 +1,5 @@
import { describe, expect, test } from 'vitest'
import { getDOM } from '#src/tests/helpers/e2etest.js'
describe('permission statements', () => {

View File

@@ -1,3 +1,5 @@
import { describe, expect, test } from 'vitest'
import { getDOMCached as getDOM } from '#src/tests/helpers/e2etest.js'
describe('sidebar', () => {

View File

@@ -1,4 +1,4 @@
import { expect } from '@jest/globals'
import { describe, expect, test } from 'vitest'
import { TRANSLATIONS_FIXTURE_ROOT } from '#src/frame/lib/constants.js'
import { getDOM } from '#src/tests/helpers/e2etest.js'

View File

@@ -1,3 +1,5 @@
import { describe, expect, test } from 'vitest'
import { getDOM, head } from '#src/tests/helpers/e2etest.js'
import { supported } from '#src/versions/lib/enterprise-server-releases.js'

View File

@@ -1,4 +1,4 @@
import { describe } from '@jest/globals'
import { describe, expect, test } from 'vitest'
import { getDOM } from '#src/tests/helpers/e2etest.js'

View File

@@ -1,9 +1,9 @@
import { expect, jest, test } from '@jest/globals'
import { describe, expect, test, vi } from 'vitest'
import { get } from '#src/tests/helpers/e2etest.js'
describe('general /api pages', () => {
jest.setTimeout(60 * 1000)
vi.setConfig({ testTimeout: 60 * 1000 })
test("any /api URL that isn't found should JSON", async () => {
const res = await get('/api')

View File

@@ -1,3 +1,5 @@
import { describe, expect, test } from 'vitest'
import { blockIndex } from '#src/frame/middleware/block-robots.js'
import { productMap } from '#src/products/lib/all-products.js'
import enterpriseServerReleases from '#src/versions/lib/enterprise-server-releases.js'

View File

@@ -1,5 +1,6 @@
import path from 'path'
import { describe, expect, test } from 'vitest'
import walk from 'walk-sync'
import createTree from '#src/frame/lib/create-tree.js'

View File

@@ -1,10 +1,10 @@
import { expect, jest } from '@jest/globals'
import { describe, expect, test, vi } from 'vitest'
import { SURROGATE_ENUMS } from '#src/frame/middleware/set-fastly-surrogate-key.js'
import { get } from '#src/tests/helpers/e2etest.js'
describe('favicon assets', () => {
jest.setTimeout(60 * 1000)
vi.setConfig({ testTimeout: 60 * 1000 })
test('should serve a valid and aggressively caching /favicon.ico', async () => {
const res = await get('/favicon.ico')

View File

@@ -2,7 +2,7 @@ import { fileURLToPath } from 'url'
import path from 'path'
import http from 'http'
import { expect, describe, test } from '@jest/globals'
import { describe, expect, test } from 'vitest'
import Page from '#src/frame/lib/page.js'
import findPage from '#src/frame/middleware/find-page.js'

View File

@@ -1,12 +1,15 @@
import { jest } from '@jest/globals'
import { fileURLToPath } from 'url'
import path from 'path'
import { describe, expect, test, vi } from 'vitest'
import Page from '#src/frame/lib/page.js'
import findPage from '#src/frame/lib/find-page.js'
const __dirname = path.dirname(fileURLToPath(import.meta.url))
describe('find page', () => {
jest.setTimeout(1000 * 1000)
vi.setConfig({ testTimeout: 60 * 1000 })
test('follows redirects', async () => {
const page = await Page.init({

View File

@@ -3,8 +3,9 @@ import path from 'path'
import os from 'os'
import { rimraf } from 'rimraf'
import { expect, test, describe, beforeAll, afterAll } from '@jest/globals'
import { afterAll, afterEach, beforeAll, describe, expect, test } from 'vitest'
import nock from 'nock'
import getRemoteJSON, { cache } from '#src/frame/lib/get-remote-json.js'
/**

View File

@@ -1,5 +1,8 @@
import fs from 'fs/promises'
import path from 'path'
import { describe, expect, test } from 'vitest'
const gitignorePath = path.join(process.cwd(), '.gitignore')
const gitignore = await fs.readFile(gitignorePath, 'utf8')
const entries = gitignore.split(/\r?\n/)

View File

@@ -1,3 +1,4 @@
import { describe, expect, test } from 'vitest'
import sharp from 'sharp'
import { SURROGATE_ENUMS } from '#src/frame/middleware/set-fastly-surrogate-key.js'

View File

@@ -1,4 +1,5 @@
import { expect } from '@jest/globals'
import { describe, expect, test } from 'vitest'
import getMiniTocItems from '#src/frame/lib/get-mini-toc-items'
function generateHeading(h) {

View File

@@ -1,9 +1,9 @@
import { describe, expect, jest, test } from '@jest/globals'
import { describe, expect, test, vi } from 'vitest'
import { get } from '#src/tests/helpers/e2etest.js'
describe('bad requests', () => {
jest.setTimeout(60 * 1000)
vi.setConfig({ testTimeout: 60 * 1000 })
test('any _next/image request should 404', async () => {
const res = await get('/_next/image?what=ever')

View File

@@ -1,7 +1,8 @@
import { fileURLToPath } from 'url'
import path from 'path'
import cheerio from 'cheerio'
import { describe, expect } from '@jest/globals'
import { beforeAll, beforeEach, describe, expect, test } from 'vitest'
import Page, { FrontmatterErrorsError } from '#src/frame/lib/page.js'
import { allVersions } from '#src/versions/lib/all-versions.js'

View File

@@ -1,18 +1,21 @@
import { jest } from '@jest/globals'
import path from 'path'
import { beforeAll, describe, expect, test, vi } from 'vitest'
import GithubSlugger from 'github-slugger'
import { decode } from 'html-entities'
import { chain, pick } from 'lodash-es'
import { loadPages } from '#src/frame/lib/page-data.js'
import libLanguages from '#src/languages/lib/languages.js'
import { liquid } from '#src/content-render/index.js'
import patterns from '#src/frame/lib/patterns.js'
import GithubSlugger from 'github-slugger'
import { decode } from 'html-entities'
import { chain, pick } from 'lodash-es'
import removeFPTFromPath from '#src/versions/lib/remove-fpt-from-path.js'
const languageCodes = Object.keys(libLanguages)
const slugger = new GithubSlugger()
describe('pages module', () => {
jest.setTimeout(60 * 1000)
vi.setConfig({ testTimeout: 60 * 1000 })
let pages

Some files were not shown because too many files have changed in this diff Show More