🌐 AI搜索 & 代理 主页
Skip to content

Commit b02a257

Browse files
authored
Build: Run GitHub Action browser tests on Playwright WebKit
So far, we've been running browser tests on GitHub Actions in Chrome and Firefox. Regular Safari is not available in GitHub Actions but Playwright WebKit comes close to a dev version of Safari. With this change, our GitHub CI & local test runs will invoke tests on all actively developed browser engines on all PRs. Also, our GitHub Actions browser tests are now running on Node.js 18. Detection of the Playwright WebKit browser in support unit tests is done by checking if the `test_browser` query parameter is set to `"Playwright"`; this is a `karma-webkit-launcher` feature. Detecting that browser via user agent as we normally do is hard as the UA on Linux is very similar to a real Safari one but it actually uses a newer version of the engine. In addition, we now allow to pass custom browsers when one needs it; e.g., to run the tests in all three engines on Linux/macOS, run: ``` grunt && BROWSERS=ChromeHeadless,FirefoxHeadless,WebkitHeadless grunt karma:main ``` Closes gh-5190
1 parent ce90a48 commit b02a257

File tree

7 files changed

+69
-38
lines changed

7 files changed

+69
-38
lines changed

.github/workflows/node.js.yml

Lines changed: 18 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -16,32 +16,32 @@ jobs:
1616
NODE_VERSION: [10.x, 14.x, 16.x, 18.x, 19.x]
1717
NPM_SCRIPT: ["test:browserless"]
1818
include:
19-
- NAME: "Browser tests: full build, Chrome & Firefox stable"
20-
NODE_VERSION: "16.x"
19+
- NAME: "Browser tests: full build, Chrome, Firefox & WebKit"
20+
NODE_VERSION: "18.x"
2121
NPM_SCRIPT: "test:browser"
22-
BROWSERS: "ChromeHeadless,FirefoxHeadless"
23-
- NAME: "Browser tests: slim build, Chrome stable"
24-
NODE_VERSION: "16.x"
22+
BROWSERS: "ChromeHeadless,FirefoxHeadless,WebkitHeadless"
23+
- NAME: "Browser tests: slim build, Chrome"
24+
NODE_VERSION: "18.x"
2525
NPM_SCRIPT: "test:slim"
2626
BROWSERS: "ChromeHeadless"
27-
- NAME: "Browser tests: no-deprecated build, Chrome stable"
28-
NODE_VERSION: "16.x"
27+
- NAME: "Browser tests: no-deprecated build, Chrome"
28+
NODE_VERSION: "18.x"
2929
NPM_SCRIPT: "test:no-deprecated"
3030
BROWSERS: "ChromeHeadless"
31-
- NAME: "Browser tests: selector-native build, Chrome stable"
32-
NODE_VERSION: "16.x"
31+
- NAME: "Browser tests: selector-native build, Chrome"
32+
NODE_VERSION: "18.x"
3333
NPM_SCRIPT: "test:selector-native"
3434
BROWSERS: "ChromeHeadless"
35-
- NAME: "Browser tests: ES modules build, Chrome stable"
36-
NODE_VERSION: "16.x"
35+
- NAME: "Browser tests: ES modules build, Chrome"
36+
NODE_VERSION: "18.x"
3737
NPM_SCRIPT: "test:esmodules"
3838
BROWSERS: "ChromeHeadless"
39-
- NAME: "Browser tests: AMD build, Chrome stable"
40-
NODE_VERSION: "16.x"
39+
- NAME: "Browser tests: AMD build, Chrome"
40+
NODE_VERSION: "18.x"
4141
NPM_SCRIPT: "test:amd"
4242
BROWSERS: "ChromeHeadless"
4343
- NAME: "Browser tests: full build, Firefox ESR"
44-
NODE_VERSION: "16.x"
44+
NODE_VERSION: "18.x"
4545
NPM_SCRIPT: "test:browser"
4646
BROWSERS: "FirefoxHeadless"
4747
steps:
@@ -71,6 +71,10 @@ jobs:
7171
run: |
7272
npm install
7373
74+
- name: Install Playwright dependencies
75+
run: npx playwright-webkit install-deps
76+
if: "matrix.NPM_SCRIPT == 'test:browser'"
77+
7478
- name: Run tests
7579
env:
7680
BROWSERS: ${{ matrix.BROWSERS }}

Gruntfile.js

Lines changed: 20 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@
22

33
module.exports = function( grunt ) {
44
function readOptionalJSON( filepath ) {
5-
var stripJSONComments = require( "strip-json-comments" ),
6-
data = {};
5+
const stripJSONComments = require( "strip-json-comments" );
6+
let data = {};
77
try {
88
data = JSON.parse( stripJSONComments(
99
fs.readFileSync( filepath, { encoding: "utf8" } )
@@ -12,19 +12,23 @@ module.exports = function( grunt ) {
1212
return data;
1313
}
1414

15-
// Support: Node.js <12
16-
// Skip running tasks that dropped support for Node.js 10
15+
const fs = require( "fs" );
16+
const gzip = require( "gzip-js" );
17+
const nodeV14OrNewer = !/^v1[0-3]\./.test( process.version );
18+
const nodeV17OrNewer = !/^v1[0-6]\./.test( process.version );
19+
const customBrowsers = process.env.BROWSERS && process.env.BROWSERS.split( "," );
20+
21+
// Support: Node.js <14
22+
// Skip running tasks that dropped support for Node.js 10 or 12
1723
// in this Node version.
1824
function runIfNewNode( task ) {
19-
return oldNode ? "print_old_node_message:" + task : task;
25+
return nodeV14OrNewer ? task : "print_old_node_message:" + task;
2026
}
2127

22-
var fs = require( "fs" ),
23-
gzip = require( "gzip-js" ),
24-
oldNode = /^v10\./.test( process.version ),
25-
nodeV17OrNewer = !/^v1[0246]\./.test( process.version ),
26-
isCi = process.env.GITHUB_ACTION,
27-
ciBrowsers = process.env.BROWSERS && process.env.BROWSERS.split( "," );
28+
if ( nodeV14OrNewer ) {
29+
const playwright = require( "playwright-webkit" );
30+
process.env.WEBKIT_HEADLESS_BIN = playwright.webkit.executablePath();
31+
}
2832

2933
if ( !grunt.option( "filename" ) ) {
3034
grunt.option( "filename", "jquery.js" );
@@ -242,10 +246,11 @@ module.exports = function( grunt ) {
242246
singleRun: true
243247
},
244248
main: {
245-
browsers: isCi && ciBrowsers || [ "ChromeHeadless", "FirefoxHeadless" ]
249+
browsers: customBrowsers ||
250+
[ "ChromeHeadless", "FirefoxHeadless", "WebkitHeadless" ]
246251
},
247252
esmodules: {
248-
browsers: isCi && ciBrowsers || [ "ChromeHeadless" ],
253+
browsers: customBrowsers || [ "ChromeHeadless" ],
249254
options: {
250255
client: {
251256
qunit: {
@@ -260,7 +265,7 @@ module.exports = function( grunt ) {
260265
}
261266
},
262267
amd: {
263-
browsers: isCi && ciBrowsers || [ "ChromeHeadless" ],
268+
browsers: customBrowsers || [ "ChromeHeadless" ],
264269
options: {
265270
client: {
266271
qunit: {
@@ -352,7 +357,7 @@ module.exports = function( grunt ) {
352357

353358
// Load grunt tasks from NPM packages
354359
require( "load-grunt-tasks" )( grunt, {
355-
pattern: oldNode ? [ "grunt-*", "!grunt-eslint" ] : [ "grunt-*" ]
360+
pattern: nodeV14OrNewer ? [ "grunt-*" ] : [ "grunt-*", "!grunt-eslint" ]
356361
} );
357362

358363
// Integrate jQuery specific tasks

package.json

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@
2323
"url": "https://github.com/jquery/jquery/issues"
2424
},
2525
"license": "MIT",
26-
"dependencies": {},
2726
"devDependencies": {
2827
"@babel/core": "7.10.5",
2928
"@babel/plugin-transform-for-of": "7.10.4",
@@ -47,15 +46,17 @@
4746
"gzip-js": "0.3.2",
4847
"husky": "4.2.5",
4948
"jsdom": "19.0.0",
50-
"karma": "^6.3.17",
49+
"karma": "6.4.1",
5150
"karma-browserstack-launcher": "1.6.0",
5251
"karma-chrome-launcher": "3.1.1",
5352
"karma-firefox-launcher": "2.1.2",
5453
"karma-ie-launcher": "1.0.0",
5554
"karma-jsdom-launcher": "12.0.0",
5655
"karma-qunit": "4.1.2",
56+
"karma-webkit-launcher": "2.1.0",
5757
"load-grunt-tasks": "5.1.0",
5858
"native-promise-only": "0.8.1",
59+
"playwright-webkit": "1.29.2",
5960
"promises-aplus-tests": "2.1.2",
6061
"q": "1.5.1",
6162
"qunit": "2.10.1",

test/unit/ajax.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2270,7 +2270,7 @@ if ( typeof window.ArrayBuffer === "undefined" || typeof new XMLHttpRequest().re
22702270
// beforeunload, unload, pagehide, and visibilitychange event handlers.
22712271
// See https://bugs.chromium.org/p/chromium/issues/detail?id=952452
22722272
// Safari 13 did similar changes. The below check will catch them both.
2273-
if ( !/safari/i.test( navigator.userAgent ) ) {
2273+
if ( !/webkit/i.test( navigator.userAgent ) ) {
22742274
testIframe(
22752275
"trac-14379 - jQuery.ajax() on unload",
22762276
"ajax/onunload.html",

test/unit/css.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1757,7 +1757,7 @@ QUnit.testUnlessIE( "css(--customProperty)", function( assert ) {
17571757
var div = jQuery( "<div>" ).appendTo( "#qunit-fixture" ),
17581758
$elem = jQuery( "<div>" ).addClass( "test__customProperties" )
17591759
.appendTo( "#qunit-fixture" ),
1760-
webkitOrBlink = /\bsafari\b/i.test( navigator.userAgent ),
1760+
webkitOrBlink = /\webkit\b/i.test( navigator.userAgent ),
17611761
expected = 20;
17621762

17631763
if ( webkitOrBlink ) {

test/unit/selector.js

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
11
QUnit.module( "selector", {
22
beforeEach: function() {
3-
this.safari = /\bsafari\b/i.test( navigator.userAgent ) &&
4-
!/\b(?:headless)?chrome\b/i.test( navigator.userAgent );
3+
4+
// Playwright WebKit on macOS doesn't expose `Safari` in its user agent
5+
// string; use the "AppleWebKit" token. This token is also present
6+
// in the Chromium UA, but it is locked to an older version there.
7+
// Modern WebKit (Safari 13+) locks it to `605.1.15`.
8+
this.safari = /\bapplewebkit\/605\.1\.15\b/i.test( navigator.userAgent );
59
},
610
afterEach: moduleTeardown
711
} );

test/unit/support.js

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,10 @@ testIframe(
7070
cssSupportsSelector: false,
7171
reliableTrDimensions: true
7272
},
73+
webkit: {
74+
cssSupportsSelector: true,
75+
reliableTrDimensions: true
76+
},
7377
firefox_102: {
7478
cssSupportsSelector: false,
7579
reliableTrDimensions: false
@@ -97,14 +101,26 @@ testIframe(
97101

98102
// Catches Edge, Chrome on Android & Opera as well.
99103
expected = expectedMap.chrome;
100-
} else if ( /\b\d+(\.\d+)+ safari/i.test( userAgent ) ) {
101-
expected = expectedMap.safari;
102104
} else if ( /firefox\/102\./i.test( userAgent ) ) {
103105
expected = expectedMap.firefox_102;
104106
} else if ( /firefox/i.test( userAgent ) ) {
105107
expected = expectedMap.firefox;
106108
} else if ( /(?:iphone|ipad);.*(?:iphone)? os \d+_/i.test( userAgent ) ) {
107109
expected = expectedMap.ios;
110+
} else if ( typeof URLSearchParams !== "undefined" &&
111+
112+
// `karma-webkit-launcher` adds `test_browser=Playwright` to the query string.
113+
// The normal way of using user agent to detect the browser won't help
114+
// as on macOS Playwright doesn't specify the `Safari` token but on Linux
115+
// it does.
116+
// See https://github.com/google/karma-webkit-launcher#detected-if-safari-or-playwright-is-used
117+
new URLSearchParams( document.referrer || window.location.search ).get(
118+
"test_browser"
119+
) === "Playwright"
120+
) {
121+
expected = expectedMap.webkit;
122+
} else if ( /\b\d+(\.\d+)+ safari/i.test( userAgent ) ) {
123+
expected = expectedMap.safari;
108124
}
109125

110126
QUnit.test( "Verify that support tests resolve as expected per browser", function( assert ) {
@@ -134,7 +150,8 @@ testIframe(
134150
for ( i in expected ) {
135151
assert.equal( computedSupport[ i ], expected[ i ],
136152
"jQuery.support['" + i + "']: " + computedSupport[ i ] +
137-
", expected['" + i + "']: " + expected[ i ] );
153+
", expected['" + i + "']: " + expected[ i ] +
154+
";\nUser Agent: " + navigator.userAgent );
138155
}
139156
} );
140157

0 commit comments

Comments
 (0)