diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index fd000ba19665..5aaaca75e63b 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -28,10 +28,10 @@ jobs:
GITHUB_CONTEXT_PR_BASE_SHA: ${{ github.event.pull_request.base.sha }}
GITHUB_CONTEXT_BASE_SHA: ${{ github.event.before }}
- - name: Use Node.js 16.x
+ - name: Use Node.js 18.x
uses: actions/setup-node@v3
with:
- node-version: 16.x
+ node-version: 18.x
- run: yarn install --frozen-lockfile --network-timeout 1000000
- run: yarn type-check
diff --git a/.github/workflows/cron-weekly.yml b/.github/workflows/cron-weekly.yml
index 8c8aee48bb6c..aa11b3c0fd1e 100644
--- a/.github/workflows/cron-weekly.yml
+++ b/.github/workflows/cron-weekly.yml
@@ -31,10 +31,10 @@ jobs:
steps:
- name: git clone
uses: actions/checkout@v3
- - name: Use Node.js 16.x
+ - name: Use Node.js 18.x
uses: actions/setup-node@v3
with:
- node-version: 16.x
+ node-version: 18.x
- run: yarn --frozen-lockfile
- run: yarn mocha --testMatch=third-party/chromium-synchronization/*-test.js
diff --git a/.github/workflows/devtools.yml b/.github/workflows/devtools.yml
index e00c1b4b2633..6ef816372fa1 100644
--- a/.github/workflows/devtools.yml
+++ b/.github/workflows/devtools.yml
@@ -25,10 +25,10 @@ jobs:
with:
path: lighthouse
- - name: Use Node.js 16.x
+ - name: Use Node.js 18.x
uses: actions/setup-node@v3
with:
- node-version: 16.x
+ node-version: 18.x
- name: Generate cache hash
run: bash $GITHUB_WORKSPACE/lighthouse/.github/scripts/generate-devtools-hash.sh > cdt-test-hash.txt
@@ -91,10 +91,10 @@ jobs:
with:
path: lighthouse
- - name: Use Node.js 16.x
+ - name: Use Node.js 18.x
uses: actions/setup-node@v3
with:
- node-version: 16.x
+ node-version: 18.x
- run: yarn --frozen-lockfile --network-timeout 1000000
working-directory: ${{ github.workspace }}/lighthouse
@@ -136,10 +136,10 @@ jobs:
with:
path: lighthouse
- - name: Use Node.js 16.x
+ - name: Use Node.js 18.x
uses: actions/setup-node@v3
with:
- node-version: 16.x
+ node-version: 18.x
- name: Load build artifacts
id: devtools-build-artifacts
diff --git a/.github/workflows/package-test.yml b/.github/workflows/package-test.yml
index aee0150d0aa6..4b225b130fc0 100644
--- a/.github/workflows/package-test.yml
+++ b/.github/workflows/package-test.yml
@@ -19,10 +19,10 @@ jobs:
- name: git clone
uses: actions/checkout@v3
- - name: Use Node.js 16.x
+ - name: Use Node.js 18.x
uses: actions/setup-node@v3
with:
- node-version: 16.x
+ node-version: 18.x
- run: yarn install --frozen-lockfile --network-timeout 1000000
- run: yarn build-report
diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml
index 0abf5a1b4090..0fb44e56df52 100644
--- a/.github/workflows/publish.yml
+++ b/.github/workflows/publish.yml
@@ -31,7 +31,7 @@ jobs:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
- node-version: 16.x
+ node-version: 18.x
registry-url: https://registry.npmjs.org/
- run: yarn --frozen-lockfile
diff --git a/.github/workflows/smoke.yml b/.github/workflows/smoke.yml
index da08f3599941..0be997f4f5ca 100644
--- a/.github/workflows/smoke.yml
+++ b/.github/workflows/smoke.yml
@@ -35,10 +35,10 @@ jobs:
# Depth of at least 2 for codecov coverage diffs. See https://github.com/GoogleChrome/lighthouse/pull/12079
fetch-depth: 2
- - name: Use Node.js 16.x
+ - name: Use Node.js 18.x
uses: actions/setup-node@v3
with:
- node-version: 16.x
+ node-version: 18.x
- name: Define ToT chrome path
if: matrix.chrome-channel == 'ToT'
@@ -138,10 +138,10 @@ jobs:
- name: git clone
uses: actions/checkout@v3
- - name: Use Node.js 16.x
+ - name: Use Node.js 18.x
uses: actions/setup-node@v3
with:
- node-version: 16.x
+ node-version: 18.x
- run: yarn install --frozen-lockfile --network-timeout 1000000
- run: yarn build-report
diff --git a/.github/workflows/unit.yml b/.github/workflows/unit.yml
index 40d3a3005acf..9f07711e16ff 100644
--- a/.github/workflows/unit.yml
+++ b/.github/workflows/unit.yml
@@ -13,7 +13,7 @@ jobs:
unit:
strategy:
matrix:
- node: ['16', '18']
+ node: ['18', '20']
fail-fast: false
runs-on: ubuntu-latest
name: node ${{ matrix.node }}
@@ -93,10 +93,10 @@ jobs:
- name: git clone
uses: actions/checkout@v3
- - name: Use Node.js 16.x
+ - name: Use Node.js 18.x
uses: actions/setup-node@v3
with:
- node-version: 16.x
+ node-version: 18.x
- run: yarn install --frozen-lockfile --network-timeout 1000000
- run: yarn build-report
diff --git a/cli/test/cli/index-test.js b/cli/test/cli/index-test.js
index e9e04c953851..0897129b3df8 100644
--- a/cli/test/cli/index-test.js
+++ b/cli/test/cli/index-test.js
@@ -76,7 +76,8 @@ describe('CLI Tests', function() {
const ret = spawnSync('node', [indexPath, 'https://www.google.com',
'--extra-headers', '{notjson}'], {encoding: 'utf8'});
- assert.ok(ret.stderr.includes('Unexpected token'));
+ // This message was changed in Node 20, check for old and new versions.
+ assert.ok(/(Unexpected token|Expected property name)/.test(ret.stderr));
assert.equal(ret.status, 1);
});
});
diff --git a/cli/test/fixtures/static-server.js b/cli/test/fixtures/static-server.js
index e06319549aa9..e402c7c501aa 100644
--- a/cli/test/fixtures/static-server.js
+++ b/cli/test/fixtures/static-server.js
@@ -169,7 +169,10 @@ class Server {
headers['X-TotalFetchedSize'] = Buffer.byteLength(data) + JSON.stringify(headers).length;
}
- response.writeHead(statusCode, headers);
+ response.statusCode = statusCode;
+ for (const [name, value] of Object.entries(headers)) {
+ response.setHeader(name, value);
+ }
const encoding = charset === 'UTF-8' ? 'utf-8' : 'binary';
// Delay the response
@@ -188,9 +191,8 @@ class Server {
Smoke test fixtures
${fixturePaths.map(p => `${escape(p)}`).join('
')}
`;
- response.writeHead(200, {
- 'Content-Security-Policy': `default-src 'none';`,
- });
+ response.statusCode = 200;
+ response.setHeader('Content-Security-Policy', `default-src 'none';`);
sendResponse(200, html);
return;
}
@@ -227,16 +229,14 @@ class Server {
function sendRedirect(url) {
// Redirects can only contain ASCII characters.
if (url.split('').some(char => char.charCodeAt(0) > 256)) {
- response.writeHead(500);
+ response.statusCode = 500;
response.write(`Invalid redirect URL: ${url}`);
response.end();
return;
}
- const headers = {
- Location: url,
- };
- response.writeHead(302, headers);
+ response.statusCode = 302;
+ response.setHeader('Location', url);
response.end();
}
diff --git a/cli/test/smokehouse/lighthouse-runners/bundle.js b/cli/test/smokehouse/lighthouse-runners/bundle.js
index 0c36c90d0fb1..f4cbc180baf0 100644
--- a/cli/test/smokehouse/lighthouse-runners/bundle.js
+++ b/cli/test/smokehouse/lighthouse-runners/bundle.js
@@ -82,7 +82,7 @@ async function runBundledLighthouse(url, config, testRunnerOptions) {
const logLevel = testRunnerOptions.isDebug ? 'verbose' : 'info';
// Puppeteer is not included in the bundle, we must create the page here.
- const browser = await puppeteer.connect({browserURL: `http://localhost:${port}`});
+ const browser = await puppeteer.connect({browserURL: `http://127.0.0.1:${port}`});
const page = await browser.newPage();
const runnerResult = await lighthouse(url, {port, logLevel}, config, page);
if (!runnerResult) throw new Error('No runnerResult');
diff --git a/core/scripts/gcp-collection/gcp-setup.sh b/core/scripts/gcp-collection/gcp-setup.sh
index 69f7240f65d3..a6b81874d77a 100644
--- a/core/scripts/gcp-collection/gcp-setup.sh
+++ b/core/scripts/gcp-collection/gcp-setup.sh
@@ -17,7 +17,7 @@ echo "deb [arch=amd64] http://dl.google.com/linux/chrome/deb/ stable main" | sud
wget -q -O - https://dl.google.com/linux/linux_signing_key.pub | sudo apt-key add -
# Node apt-key
-curl -sL https://deb.nodesource.com/setup_16.x | sudo -E bash -
+curl -sL https://deb.nodesource.com/setup_18.x | sudo -E bash -
# Install dependencies
sudo apt-get update
diff --git a/core/scripts/lantern/collect/gcp-setup.sh b/core/scripts/lantern/collect/gcp-setup.sh
index 66b78d4a9aca..563bd9afe31f 100644
--- a/core/scripts/lantern/collect/gcp-setup.sh
+++ b/core/scripts/lantern/collect/gcp-setup.sh
@@ -11,7 +11,7 @@ echo "deb [arch=amd64] http://dl.google.com/linux/chrome/deb/ stable main" | sud
wget -q -O - https://dl.google.com/linux/linux_signing_key.pub | sudo apt-key add -
# Node apt-key
-curl -sL https://deb.nodesource.com/setup_16.x | sudo -E bash -
+curl -sL https://deb.nodesource.com/setup_18.x | sudo -E bash -
# Install dependencies
sudo apt-get update
diff --git a/core/test/config/config-helpers-test.js b/core/test/config/config-helpers-test.js
index ab5ec6ecf85b..e40d71a971d0 100644
--- a/core/test/config/config-helpers-test.js
+++ b/core/test/config/config-helpers-test.js
@@ -424,7 +424,7 @@ describe('.resolveGathererToDefn', () => {
it('throws but not for missing gatherer when it has a node dependency error', async () => {
const resultPromise =
resolveGathererToDefn('../fixtures/invalid-gatherers/require-error.js', [], moduleDir);
- await expect(resultPromise).rejects.toThrow(/Cannot find module/);
+ await expect(resultPromise).rejects.toThrow(/no such file or directory/);
});
});
@@ -502,7 +502,7 @@ describe('.resolveAuditsToDefns', () => {
const resultPromise = resolveAuditsToDefns([
'../fixtures/invalid-audits/require-error.js',
], moduleDir);
- await expect(resultPromise).rejects.toThrow(/Cannot find module/);
+ await expect(resultPromise).rejects.toThrow(/no such file or directory/);
});
});
diff --git a/core/test/gather/gatherers/source-maps-test.js b/core/test/gather/gatherers/source-maps-test.js
index 1c9bac998ac4..107cdd5c4d19 100644
--- a/core/test/gather/gatherers/source-maps-test.js
+++ b/core/test/gather/gatherers/source-maps-test.js
@@ -241,13 +241,17 @@ describe('SourceMaps gatherer', () => {
{
scriptUrl: mapsAndEvents[0].script.name,
sourceMapUrl: mapsAndEvents[0].script.sourceMapURL,
- errorMessage: 'SyntaxError: Unexpected token { in JSON at position 1',
+ // This message was changed in Node 20, check for old and new versions.
+ // eslint-disable-next-line max-len
+ errorMessage: expect.stringMatching(/(Expected property name|Unexpected token).*at position 1/),
map: undefined,
},
{
scriptUrl: mapsAndEvents[1].script.name,
sourceMapUrl: undefined,
- errorMessage: 'SyntaxError: Unexpected token ; in JSON at position 2',
+ // This message was changed in Node 20, check for old and new versions.
+ // eslint-disable-next-line max-len
+ errorMessage: expect.stringMatching(/(Unexpected non-whitespace|Unexpected token).*at position 2/),
map: undefined,
},
]);
diff --git a/docs/headless-chrome.md b/docs/headless-chrome.md
index e0166211ad3d..f1b4ced26d1e 100644
--- a/docs/headless-chrome.md
+++ b/docs/headless-chrome.md
@@ -5,8 +5,8 @@
Setup:
```sh
-# Lighthouse requires Node 16 LTS (16.x) or later.
-curl -sL https://deb.nodesource.com/setup_14.x | sudo -E bash - &&\
+# Lighthouse requires Node 18 LTS (18.x) or later.
+curl -sL https://deb.nodesource.com/setup_18.x | sudo -E bash - &&\
sudo apt-get install -y nodejs npm
# get chromium (stable)
@@ -27,8 +27,8 @@ lighthouse --chrome-flags="--headless" https://github.com
Alternatively, you can run full Chrome + xvfb instead of headless mode. These steps worked on Debian Jessie:
```sh
-# get node 16
-curl -sL https://deb.nodesource.com/setup_16.x | sudo -E bash -
+# get node 18
+curl -sL https://deb.nodesource.com/setup_18.x | sudo -E bash -
sudo apt-get install -y nodejs npm
# get chromium (stable) and Xvfb
diff --git a/package.json b/package.json
index 4fc00411ca69..0253cd3c5985 100644
--- a/package.json
+++ b/package.json
@@ -10,7 +10,7 @@
"smokehouse": "./cli/test/smokehouse/frontends/smokehouse-bin.js"
},
"engines": {
- "node": ">=16.16"
+ "node": ">=18.16"
},
"scripts": {
"prepack": "yarn build-report --standalone --flow --esm && yarn build-types",
@@ -172,7 +172,7 @@
"rollup-plugin-polyfill-node": "^0.12.0",
"tabulator-tables": "^4.9.3",
"terser": "^5.18.2",
- "testdouble": "^3.17.2",
+ "testdouble": "^3.18.0",
"typed-query-selector": "^2.6.1",
"typescript": "^5.0.4",
"wait-for-expect": "^3.0.2",
diff --git a/readme.md b/readme.md
index 9607b6a59635..9041ad7fa460 100644
--- a/readme.md
+++ b/readme.md
@@ -52,7 +52,7 @@ The Chrome extension was available prior to Lighthouse being available in Chrome
The Node CLI provides the most flexibility in how Lighthouse runs can be configured and reported. Users who want more advanced usage, or want to run Lighthouse in an automated fashion should use the Node CLI.
-_Lighthouse requires Node 16 LTS (16.x) or later._
+_Lighthouse requires Node 18 LTS (18.x) or later._
**Installation**:
diff --git a/yarn.lock b/yarn.lock
index d8571de2012f..9295f23520b1 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -6001,10 +6001,10 @@ queue-tick@^1.0.1:
resolved "https://registry.yarnpkg.com/queue-tick/-/queue-tick-1.0.1.tgz#f6f07ac82c1fd60f82e098b417a80e52f1f4c142"
integrity sha512-kJt5qhMxoszgU/62PLP1CJytzd2NKetjSRnyuj31fDd3Rlcz3fzlFdFLD1SItunPwyqEOkca6GbV612BWfaBag==
-quibble@^0.6.17:
- version "0.6.17"
- resolved "https://registry.yarnpkg.com/quibble/-/quibble-0.6.17.tgz#1c47d40c4ee670fc1a5a4277ee792ca6eec8f4ca"
- integrity sha512-uybGnGrx1hAhBCmzmVny+ycKaS5F71+q+iWVzbf8x/HyeEMDGeiQFVjWl1zhi4rwfTHa05+/NIExC4L5YRNPjQ==
+quibble@^0.7.0:
+ version "0.7.0"
+ resolved "https://registry.yarnpkg.com/quibble/-/quibble-0.7.0.tgz#fd7f7f03ed4c2682b55523433af5e66bc26bde9f"
+ integrity sha512-uiqtYLo6p6vWR/G3Ltsg0NU1xw43RcNGadYP+d/DF3zLQTyOt8uC7L2mmcJ97au1QE1YdmCD+HVIIq/RGtkbWA==
dependencies:
lodash "^4.17.21"
resolve "^1.22.1"
@@ -6827,13 +6827,13 @@ test-exclude@^6.0.0:
glob "^7.1.4"
minimatch "^3.0.4"
-testdouble@^3.17.2:
- version "3.17.2"
- resolved "https://registry.yarnpkg.com/testdouble/-/testdouble-3.17.2.tgz#a7d624c2040453580b4a636b3f017bf183a8f487"
- integrity sha512-oRrk1DJISNoFr3aaczIqrrhkOUQ26BsXN3SopYT/U0GTvk9hlKPCEbd9R2uxkcufKZgEfo9D1JAB4CJrjHE9cw==
+testdouble@^3.18.0:
+ version "3.18.0"
+ resolved "https://registry.yarnpkg.com/testdouble/-/testdouble-3.18.0.tgz#850a04d00045a52cd08c99cb69aea6845fe86587"
+ integrity sha512-awRay/WxNHYz0SJrjvvg1xE4QQkbKgWFN1VNhhb132JSO2FSWUW4cebUtD0HjWWwrvpN3uFsVeaUhwpmVlzlkg==
dependencies:
lodash "^4.17.21"
- quibble "^0.6.17"
+ quibble "^0.7.0"
stringify-object-es5 "^2.5.0"
theredoc "^1.0.0"