Run browser tests on UMD version (#18526)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
This commit is contained in:
1 parent
06a73b700b
commit
b7055dbfb4
8 files changed
+169
-57
No files matched your search
@@ -145,7 +145,7 @@ jobs:
|
||||
working-directory: dist/prettier
|
||||
run: node bin/prettier.cjs --debug-benchmark package.json 2>&1 >/dev/null | grep "Latency avg" || exit 1
|
||||
|
||||
browser-test:
|
||||
browser:
|
||||
timeout-minutes: 15
|
||||
strategy:
|
||||
fail-fast: false
|
||||
@@ -191,8 +191,15 @@ jobs:
|
||||
name: dist
|
||||
path: dist
|
||||
|
||||
- name: Run Tests
|
||||
run: yarn test:production-browser
|
||||
- name: Run Tests (ESM)
|
||||
env:
|
||||
TEST_BUNDLE_FORMAT: esm
|
||||
run: yarn test:production:browser
|
||||
|
||||
- name: Run Tests (UMD)
|
||||
env:
|
||||
TEST_BUNDLE_FORMAT: umd
|
||||
run: yarn test:production:browser
|
||||
|
||||
cli:
|
||||
name: CLI
|
||||
|
||||
+5
-3
@@ -191,9 +191,11 @@
|
||||
"test:production-node14": "cross-env NODE_ENV=production yarn test:node14",
|
||||
"test:production-standalone": "cross-env TEST_STANDALONE=1 yarn test:production",
|
||||
"test:production-standalone-node14": "cross-env TEST_STANDALONE=1 yarn test:production-node14",
|
||||
"test:production-browser": "cross-env NODE_ENV=production TEST_RUNTIME=browser yarn test",
|
||||
"test:production-browser:chrome": "cross-env TEST_RUNTIME_BROWSER=chrome yarn test:production-browser",
|
||||
"test:production-browser:firefox": "cross-env TEST_RUNTIME_BROWSER=firefox yarn test:production-browser",
|
||||
"test:production:browser": "cross-env TEST_RUNTIME=browser yarn test:production",
|
||||
"test:production:browser:chrome": "cross-env TEST_RUNTIME_BROWSER=chrome yarn test:production:browser",
|
||||
"test:production:browser:firefox": "cross-env TEST_RUNTIME_BROWSER=firefox yarn test:production:browser",
|
||||
"test:production:browser:chrome:umd": "cross-env TEST_BUNDLE_FORMAT=umd yarn test:production:browser:chrome",
|
||||
"test:production:browser:firefox:umd": "cross-env TEST_BUNDLE_FORMAT=umd yarn test:production:browser:firefox",
|
||||
"test:production-lint": "eslint dist --config=./scripts/production-eslint-config.js --quiet --format friendly",
|
||||
"perf": "yarn && yarn build && cross-env NODE_ENV=production node ./dist/prettier/bin/prettier.cjs",
|
||||
"perf:inspect": "yarn && yarn build && cross-env NODE_ENV=production node --inspect-brk ./dist/prettier/bin/prettier.cjs",
|
||||
|
||||
+1
-2
@@ -6,7 +6,6 @@ function withPlugins(
|
||||
optionsArgumentIndex = 1, // Usually `options` is the 2nd argument
|
||||
) {
|
||||
// Returns Promises to consistent with functions in `index.js`
|
||||
// eslint-disable-next-line require-await
|
||||
return async (...args) => {
|
||||
const options = args[optionsArgumentIndex] ?? {};
|
||||
const plugins = options.plugins ?? [];
|
||||
@@ -16,7 +15,7 @@ function withPlugins(
|
||||
plugins: Array.isArray(plugins) ? plugins : Object.values(plugins),
|
||||
};
|
||||
|
||||
return fn(...args);
|
||||
return await fn(...args);
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -3,7 +3,10 @@ import { startServer } from "./server.js";
|
||||
import { requestFromNode } from "./utilities.js";
|
||||
|
||||
async function getBrowserPrettier() {
|
||||
/** @type {"chrome" | "firefox"} */
|
||||
const browserName = process.env.TEST_RUNTIME_BROWSER ?? "chrome";
|
||||
/** @type {"esm" | "umd"} */
|
||||
const prettierBundleFormat = process.env.TEST_BUNDLE_FORMAT ?? "esm";
|
||||
const browser = await launchBrowser({ browser: browserName });
|
||||
|
||||
process.once("exit", async () => {
|
||||
@@ -16,14 +19,14 @@ async function getBrowserPrettier() {
|
||||
});
|
||||
|
||||
const page = await browser.newPage();
|
||||
await page.goto(server.url + "/esm.html");
|
||||
await page.goto(server.url);
|
||||
|
||||
const proxyFunction = (accessPath, optionsIndex = 1) =>
|
||||
requestFromNode(
|
||||
(...arguments_) =>
|
||||
page.evaluate(
|
||||
([arguments_, accessPath]) => {
|
||||
const prettier = globalThis.__prettier;
|
||||
([arguments_, accessPath, prettierBundleFormat]) => {
|
||||
const prettier = globalThis[`__prettier_${prettierBundleFormat}`];
|
||||
let function_ = prettier;
|
||||
for (const property of accessPath.split(".")) {
|
||||
function_ = function_[property];
|
||||
@@ -31,7 +34,7 @@ async function getBrowserPrettier() {
|
||||
|
||||
return function_(...arguments_);
|
||||
},
|
||||
[arguments_, accessPath],
|
||||
[arguments_, accessPath, prettierBundleFormat],
|
||||
),
|
||||
{
|
||||
browser: browserName,
|
||||
|
||||
@@ -6,7 +6,10 @@
|
||||
<title>Document</title>
|
||||
</head>
|
||||
<body>
|
||||
<div>Use <code>__prettier</code> to debug in console.</div>
|
||||
<div>
|
||||
Use <code>__prettier_esm</code> or <code>__prettier_umd</code> to debug in
|
||||
console.
|
||||
</div>
|
||||
<script type="module" src="main.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
+131
-41
@@ -1,4 +1,4 @@
|
||||
import { responseInBrowser } from "./utilities.js";
|
||||
import { ensurePromise, responseInBrowser } from "./utilities.js";
|
||||
|
||||
const browser = navigator.userAgent.includes("Firefox/") ? "firefox" : "chrome";
|
||||
|
||||
@@ -22,50 +22,140 @@ const esmFiles = {
|
||||
"plugin-oxc/index.browser.mjs",
|
||||
],
|
||||
};
|
||||
const umdFiles = {
|
||||
prettier: "prettier/standalone.js",
|
||||
plugins: [
|
||||
"prettier/plugins/angular.js",
|
||||
"prettier/plugins/graphql.js",
|
||||
"prettier/plugins/typescript.js",
|
||||
"prettier/plugins/estree.js",
|
||||
"prettier/plugins/markdown.js",
|
||||
"prettier/plugins/acorn.js",
|
||||
"prettier/plugins/glimmer.js",
|
||||
"prettier/plugins/postcss.js",
|
||||
"prettier/plugins/babel.js",
|
||||
"prettier/plugins/html.js",
|
||||
"prettier/plugins/yaml.js",
|
||||
"prettier/plugins/flow.js",
|
||||
"prettier/plugins/meriyah.js",
|
||||
// These two plugins don't have umd version
|
||||
"plugin-hermes/index.mjs",
|
||||
"plugin-oxc/index.browser.mjs",
|
||||
],
|
||||
};
|
||||
|
||||
let prettier;
|
||||
let builtinPlugins;
|
||||
async function loadScript(url) {
|
||||
const { document } = globalThis;
|
||||
const { head } = document;
|
||||
const script = Object.assign(document.createElement("script"), { src: url });
|
||||
|
||||
function proxyFunction(accessPath, optionsIndex = 1) {
|
||||
let function_;
|
||||
return responseInBrowser(
|
||||
async (...arguments_) => {
|
||||
if (!prettier) {
|
||||
[prettier, ...builtinPlugins] = await Promise.all(
|
||||
[esmFiles.prettier, ...esmFiles.plugins].map(
|
||||
(file) => import(`/${file}`),
|
||||
),
|
||||
);
|
||||
}
|
||||
function on(event, callback) {
|
||||
script.addEventListener(event, callback, { once: true, passive: true });
|
||||
}
|
||||
|
||||
if (!function_) {
|
||||
function_ = prettier;
|
||||
for (const property of accessPath.split(".")) {
|
||||
function_ = function_[property];
|
||||
}
|
||||
}
|
||||
try {
|
||||
await new Promise((resolve, reject) => {
|
||||
on("load", resolve);
|
||||
|
||||
const options = arguments_[optionsIndex] ?? {};
|
||||
on("error", () => {
|
||||
reject(new Error(`Failed to load script '${url}'.`));
|
||||
});
|
||||
|
||||
arguments_[optionsIndex] = {
|
||||
...options,
|
||||
plugins: [...builtinPlugins, ...(options.plugins || [])],
|
||||
};
|
||||
|
||||
return function_(...arguments_);
|
||||
},
|
||||
{
|
||||
browser,
|
||||
accessPath,
|
||||
optionsIndex,
|
||||
},
|
||||
);
|
||||
head.appendChild(script);
|
||||
});
|
||||
} finally {
|
||||
head.removeChild(script);
|
||||
}
|
||||
}
|
||||
|
||||
globalThis.__prettier = {
|
||||
formatWithCursor: proxyFunction("formatWithCursor"),
|
||||
getSupportInfo: proxyFunction("getSupportInfo", /* optionsIndex */ 0),
|
||||
__debug: {
|
||||
parse: proxyFunction("__debug.parse"),
|
||||
},
|
||||
};
|
||||
async function loadEsmPrettier() {
|
||||
const [prettier, ...builtinPlugins] = await Promise.all(
|
||||
[esmFiles.prettier, ...esmFiles.plugins].map((file) => import(`/${file}`)),
|
||||
);
|
||||
|
||||
return { prettier, builtinPlugins };
|
||||
}
|
||||
|
||||
async function loadUmdPrettier() {
|
||||
const { umdPluginFiles, esmPluginFiles } = Object.groupBy(
|
||||
umdFiles.plugins,
|
||||
(file) => `${file.endsWith(".mjs") ? "esm" : "umd"}PluginFiles`,
|
||||
);
|
||||
|
||||
const [, esmPlugins] = await Promise.all([
|
||||
Promise.all(
|
||||
[umdFiles.prettier, ...umdPluginFiles].map((file) =>
|
||||
loadScript(`/${file}`),
|
||||
),
|
||||
),
|
||||
Promise.all(esmPluginFiles.map((file) => import(`/${file}`))),
|
||||
]);
|
||||
|
||||
const { prettier } = globalThis;
|
||||
const builtinPlugins = [
|
||||
...Object.values(globalThis.prettierPlugins),
|
||||
...esmPlugins,
|
||||
];
|
||||
delete globalThis.prettier;
|
||||
delete globalThis.prettierPlugins;
|
||||
return { prettier, builtinPlugins };
|
||||
}
|
||||
|
||||
/**
|
||||
@param {"esm" | "umd"} prettierBundleFormat
|
||||
*/
|
||||
function createPrettier(prettierBundleFormat) {
|
||||
let cache;
|
||||
function loadPrettier() {
|
||||
if (!cache) {
|
||||
cache =
|
||||
prettierBundleFormat === "esm" ? loadEsmPrettier() : loadUmdPrettier();
|
||||
}
|
||||
|
||||
return cache;
|
||||
}
|
||||
|
||||
const functions = new Map();
|
||||
|
||||
function proxyFunction(accessPath, optionsIndex = 1) {
|
||||
let function_;
|
||||
return responseInBrowser(
|
||||
async (...arguments_) => {
|
||||
const { prettier, builtinPlugins } = await loadPrettier();
|
||||
|
||||
if (!functions.has(accessPath)) {
|
||||
function_ = prettier;
|
||||
for (const property of accessPath.split(".")) {
|
||||
function_ = function_[property];
|
||||
}
|
||||
functions.set(accessPath, function_);
|
||||
}
|
||||
|
||||
const options = arguments_[optionsIndex] ?? {};
|
||||
|
||||
arguments_[optionsIndex] = {
|
||||
...options,
|
||||
plugins: [...builtinPlugins, ...(options.plugins || [])],
|
||||
};
|
||||
|
||||
return ensurePromise(function_(...arguments_));
|
||||
},
|
||||
{
|
||||
browser,
|
||||
accessPath,
|
||||
optionsIndex,
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
return {
|
||||
formatWithCursor: proxyFunction("formatWithCursor"),
|
||||
getSupportInfo: proxyFunction("getSupportInfo", /* optionsIndex */ 0),
|
||||
__debug: {
|
||||
parse: proxyFunction("__debug.parse"),
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
globalThis.__prettier_esm = createPrettier("esm");
|
||||
globalThis.__prettier_umd = createPrettier("umd");
|
||||
@@ -9,7 +9,7 @@ async function getContent(url) {
|
||||
assert.ok(url.startsWith("/"));
|
||||
url = url.slice(1);
|
||||
|
||||
if (url === "esm.html" || url === "main.js" || url === "utilities.js") {
|
||||
if (url === "index.html" || url === "main.js" || url === "utilities.js") {
|
||||
return await fs.readFile(new URL(url, import.meta.url), "utf8");
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@ async function startServer({ silent = false, port: preferredPort } = {}) {
|
||||
}
|
||||
|
||||
if (url === "/") {
|
||||
url = "/esm.html";
|
||||
url = "/index.html";
|
||||
}
|
||||
|
||||
// Only allow `.mjs`, `.js` and `.html`
|
||||
|
||||
@@ -157,4 +157,12 @@ function serializeValue(value) {
|
||||
return value;
|
||||
}
|
||||
|
||||
export { requestFromNode, responseInBrowser };
|
||||
const ensurePromise = (value) => {
|
||||
if (!(value instanceof Promise)) {
|
||||
throw new TypeError("Expected value to be a 'Promise'.");
|
||||
}
|
||||
|
||||
return value;
|
||||
};
|
||||
|
||||
export { ensurePromise, requestFromNode, responseInBrowser };
|
||||
Reference in new issue
Block a user