Default preview host to localhost (#5753)
* Initial refactor * Extract as vite plugin * Cleanup vite plugin * Reduce option passing * Use localhost as preview default host * Simplify base handling * Fix host handling * Add changeset * Remove unused imports * Remove unused sirv dep * Try pin playwright to 1.28.1 * Update playwright * Try this * Speed up CI * Try fix page off * Refactor networkidle * Ensure open connections are destroyed when the preview server is closed * Revert debug code Co-authored-by: Matthew Phillips <matthew@matthewphillips.info>
This commit is contained in:
parent
f35411487b
commit
302e0ef8f5
15 changed files with 183 additions and 270 deletions
5
.changeset/lemon-bobcats-kick.md
Normal file
5
.changeset/lemon-bobcats-kick.md
Normal file
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
'astro': major
|
||||
---
|
||||
|
||||
Default preview host to `localhost` instead of `127.0.0.1`. This allows the static server and integration preview servers to serve under ipv6.
|
|
@ -155,8 +155,8 @@
|
|||
"rehype": "^12.0.1",
|
||||
"resolve": "^1.22.0",
|
||||
"semver": "^7.3.7",
|
||||
"server-destroy": "^1.0.1",
|
||||
"shiki": "^0.11.1",
|
||||
"sirv": "^2.0.2",
|
||||
"slash": "^4.0.0",
|
||||
"string-width": "^5.1.2",
|
||||
"strip-ansi": "^7.0.1",
|
||||
|
@ -171,7 +171,7 @@
|
|||
"zod": "^3.17.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@playwright/test": "^1.22.2",
|
||||
"@playwright/test": "^1.29.2",
|
||||
"@types/babel__generator": "^7.6.4",
|
||||
"@types/babel__traverse": "^7.17.1",
|
||||
"@types/chai": "^4.3.1",
|
||||
|
@ -191,6 +191,7 @@
|
|||
"@types/resolve": "^1.20.2",
|
||||
"@types/rimraf": "^3.0.2",
|
||||
"@types/send": "^0.17.1",
|
||||
"@types/server-destroy": "^1.0.1",
|
||||
"@types/unist": "^2.0.6",
|
||||
"astro-scripts": "workspace:*",
|
||||
"chai": "^4.3.6",
|
||||
|
|
|
@ -49,9 +49,6 @@ export default async function dev(
|
|||
// Start listening to the port
|
||||
const devServerAddressInfo = await startContainer(restart.container);
|
||||
|
||||
const site = settings.config.site
|
||||
? new URL(settings.config.base, settings.config.site)
|
||||
: undefined;
|
||||
info(
|
||||
options.logging,
|
||||
null,
|
||||
|
@ -59,7 +56,7 @@ export default async function dev(
|
|||
startupTime: performance.now() - devStart,
|
||||
resolvedUrls: restart.container.viteServer.resolvedUrls || { local: [], network: [] },
|
||||
host: settings.config.server.host,
|
||||
site,
|
||||
base: settings.config.base,
|
||||
isRestart: options.isRestart,
|
||||
})
|
||||
);
|
||||
|
|
|
@ -14,14 +14,11 @@ import {
|
|||
underline,
|
||||
yellow,
|
||||
} from 'kleur/colors';
|
||||
import type { AddressInfo } from 'net';
|
||||
import os from 'os';
|
||||
import { ResolvedServerUrls } from 'vite';
|
||||
import { ZodError } from 'zod';
|
||||
import { renderErrorMarkdown } from './errors/dev/utils.js';
|
||||
import { AstroError, CompilerError, ErrorWithMetadata } from './errors/index.js';
|
||||
import { removeTrailingForwardSlash } from './path.js';
|
||||
import { emoji, getLocalAddress, padMultilineString } from './util.js';
|
||||
import { emoji, padMultilineString } from './util.js';
|
||||
|
||||
const PREFIX_PADDING = 6;
|
||||
|
||||
|
@ -58,31 +55,26 @@ export function serverStart({
|
|||
startupTime,
|
||||
resolvedUrls,
|
||||
host,
|
||||
site,
|
||||
base,
|
||||
isRestart = false,
|
||||
}: {
|
||||
startupTime: number;
|
||||
resolvedUrls: ResolvedServerUrls;
|
||||
host: string | boolean;
|
||||
site: URL | undefined;
|
||||
base: string;
|
||||
isRestart?: boolean;
|
||||
}): string {
|
||||
// PACKAGE_VERSION is injected at build-time
|
||||
const version = process.env.PACKAGE_VERSION ?? '0.0.0';
|
||||
const rootPath = site ? site.pathname : '/';
|
||||
const localPrefix = `${dim('┃')} Local `;
|
||||
const networkPrefix = `${dim('┃')} Network `;
|
||||
const emptyPrefix = ' '.repeat(11);
|
||||
|
||||
const localUrlMessages = resolvedUrls.local.map((url, i) => {
|
||||
return `${i === 0 ? localPrefix : emptyPrefix}${bold(
|
||||
cyan(removeTrailingForwardSlash(url) + rootPath)
|
||||
)}`;
|
||||
return `${i === 0 ? localPrefix : emptyPrefix}${bold(cyan(new URL(url).origin + base))}`;
|
||||
});
|
||||
const networkUrlMessages = resolvedUrls.network.map((url, i) => {
|
||||
return `${i === 0 ? networkPrefix : emptyPrefix}${bold(
|
||||
cyan(removeTrailingForwardSlash(url) + rootPath)
|
||||
)}`;
|
||||
return `${i === 0 ? networkPrefix : emptyPrefix}${bold(cyan(new URL(url).origin + base))}`;
|
||||
});
|
||||
|
||||
if (networkUrlMessages.length === 0) {
|
||||
|
@ -109,50 +101,6 @@ export function serverStart({
|
|||
.join('\n');
|
||||
}
|
||||
|
||||
export function resolveServerUrls({
|
||||
address,
|
||||
host,
|
||||
https,
|
||||
}: {
|
||||
address: AddressInfo;
|
||||
host: string | boolean;
|
||||
https: boolean;
|
||||
}): ResolvedServerUrls {
|
||||
const { address: networkAddress, port } = address;
|
||||
const localAddress = getLocalAddress(networkAddress, host);
|
||||
const networkLogging = getNetworkLogging(host);
|
||||
const toDisplayUrl = (hostname: string) => `${https ? 'https' : 'http'}://${hostname}:${port}`;
|
||||
|
||||
let local = toDisplayUrl(localAddress);
|
||||
let network: string | null = null;
|
||||
|
||||
if (networkLogging === 'visible') {
|
||||
const ipv4Networks = Object.values(os.networkInterfaces())
|
||||
.flatMap((networkInterface) => networkInterface ?? [])
|
||||
.filter(
|
||||
(networkInterface) =>
|
||||
networkInterface?.address &&
|
||||
// Node < v18
|
||||
((typeof networkInterface.family === 'string' && networkInterface.family === 'IPv4') ||
|
||||
// Node >= v18
|
||||
(typeof networkInterface.family === 'number' && (networkInterface as any).family === 4))
|
||||
);
|
||||
for (let { address: ipv4Address } of ipv4Networks) {
|
||||
if (ipv4Address.includes('127.0.0.1')) {
|
||||
const displayAddress = ipv4Address.replace('127.0.0.1', localAddress);
|
||||
local = toDisplayUrl(displayAddress);
|
||||
} else {
|
||||
network = toDisplayUrl(ipv4Address);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
local: [local],
|
||||
network: network ? [network] : [],
|
||||
};
|
||||
}
|
||||
|
||||
export function telemetryNotice() {
|
||||
const headline = yellow(`Astro now collects ${bold('anonymous')} usage data.`);
|
||||
const why = `This ${bold('optional program')} will help shape our roadmap.`;
|
||||
|
@ -228,11 +176,6 @@ export function cancelled(message: string, tip?: string) {
|
|||
.join('\n');
|
||||
}
|
||||
|
||||
/** Display port in use */
|
||||
export function portInUse({ port }: { port: number }): string {
|
||||
return `Port ${port} in use. Trying a new one…`;
|
||||
}
|
||||
|
||||
const LOCAL_IP_HOSTS = new Set(['localhost', '127.0.0.1']);
|
||||
|
||||
export function getNetworkLogging(host: string | boolean): 'none' | 'host-to-expose' | 'visible' {
|
||||
|
|
|
@ -23,11 +23,9 @@ export default async function preview(
|
|||
logging: logging,
|
||||
});
|
||||
await runHookConfigDone({ settings: settings, logging: logging });
|
||||
const host = getResolvedHostForHttpServer(settings.config.server.host);
|
||||
const { port, headers } = settings.config.server;
|
||||
|
||||
if (settings.config.output === 'static') {
|
||||
const server = await createStaticPreviewServer(settings, { logging, host, port, headers });
|
||||
const server = await createStaticPreviewServer(settings, logging);
|
||||
return server;
|
||||
}
|
||||
if (!settings.adapter) {
|
||||
|
@ -55,8 +53,8 @@ export default async function preview(
|
|||
outDir: settings.config.outDir,
|
||||
client: settings.config.build.client,
|
||||
serverEntrypoint: new URL(settings.config.build.serverEntry, settings.config.build.server),
|
||||
host,
|
||||
port,
|
||||
host: getResolvedHostForHttpServer(settings.config.server.host),
|
||||
port: settings.config.server.port,
|
||||
base: settings.config.base,
|
||||
});
|
||||
|
||||
|
|
|
@ -1,15 +1,14 @@
|
|||
import type { AddressInfo } from 'net';
|
||||
import http from 'http';
|
||||
import { performance } from 'perf_hooks';
|
||||
import { fileURLToPath } from 'url';
|
||||
import { preview, type PreviewServer as VitePreviewServer } from 'vite';
|
||||
import type { AstroSettings } from '../../@types/astro';
|
||||
import type { LogOptions } from '../logger/core';
|
||||
|
||||
import fs from 'fs';
|
||||
import http, { OutgoingHttpHeaders } from 'http';
|
||||
import { performance } from 'perf_hooks';
|
||||
import sirv from 'sirv';
|
||||
import { fileURLToPath } from 'url';
|
||||
import { notFoundTemplate, subpathNotUsedTemplate } from '../../template/4xx.js';
|
||||
import { error, info } from '../logger/core.js';
|
||||
import * as msg from '../messages.js';
|
||||
import { getResolvedHostForHttpServer } from './util.js';
|
||||
import { vitePluginAstroPreview } from './vite-plugin-astro-preview.js';
|
||||
import enableDestroy from 'server-destroy';
|
||||
|
||||
export interface PreviewServer {
|
||||
host?: string;
|
||||
|
@ -19,160 +18,65 @@ export interface PreviewServer {
|
|||
stop(): Promise<void>;
|
||||
}
|
||||
|
||||
const HAS_FILE_EXTENSION_REGEXP = /^.*\.[^\\]+$/;
|
||||
|
||||
/** The primary dev action */
|
||||
export default async function createStaticPreviewServer(
|
||||
settings: AstroSettings,
|
||||
{
|
||||
logging,
|
||||
host,
|
||||
port,
|
||||
headers,
|
||||
}: {
|
||||
logging: LogOptions;
|
||||
host: string | undefined;
|
||||
port: number;
|
||||
headers: OutgoingHttpHeaders | undefined;
|
||||
}
|
||||
logging: LogOptions
|
||||
): Promise<PreviewServer> {
|
||||
const startServerTime = performance.now();
|
||||
const defaultOrigin = 'http://localhost';
|
||||
const trailingSlash = settings.config.trailingSlash;
|
||||
/** Base request URL. */
|
||||
let baseURL = new URL(settings.config.base, new URL(settings.config.site || '/', defaultOrigin));
|
||||
const staticFileServer = sirv(fileURLToPath(settings.config.outDir), {
|
||||
dev: true,
|
||||
etag: true,
|
||||
maxAge: 0,
|
||||
setHeaders: (res, pathname, stats) => {
|
||||
for (const [name, value] of Object.entries(headers ?? {})) {
|
||||
if (value) res.setHeader(name, value);
|
||||
}
|
||||
|
||||
let previewServer: VitePreviewServer;
|
||||
try {
|
||||
previewServer = await preview({
|
||||
configFile: false,
|
||||
base: settings.config.base,
|
||||
appType: 'mpa',
|
||||
build: {
|
||||
outDir: fileURLToPath(settings.config.outDir),
|
||||
},
|
||||
});
|
||||
// Create the preview server, send static files out of the `dist/` directory.
|
||||
const server = http.createServer((req, res) => {
|
||||
const requestURL = new URL(req.url as string, defaultOrigin);
|
||||
|
||||
// respond 404 to requests outside the base request directory
|
||||
if (!requestURL.pathname.startsWith(baseURL.pathname)) {
|
||||
res.statusCode = 404;
|
||||
res.end(subpathNotUsedTemplate(baseURL.pathname, requestURL.pathname));
|
||||
return;
|
||||
}
|
||||
|
||||
/** Relative request path. */
|
||||
const pathname = requestURL.pathname.slice(baseURL.pathname.length - 1);
|
||||
|
||||
const isRoot = pathname === '/';
|
||||
const hasTrailingSlash = isRoot || pathname.endsWith('/');
|
||||
|
||||
function sendError(message: string) {
|
||||
res.statusCode = 404;
|
||||
res.end(notFoundTemplate(pathname, message));
|
||||
}
|
||||
|
||||
switch (true) {
|
||||
case hasTrailingSlash && trailingSlash == 'never' && !isRoot:
|
||||
sendError('Not Found (trailingSlash is set to "never")');
|
||||
return;
|
||||
case !hasTrailingSlash &&
|
||||
trailingSlash == 'always' &&
|
||||
!isRoot &&
|
||||
!HAS_FILE_EXTENSION_REGEXP.test(pathname):
|
||||
sendError('Not Found (trailingSlash is set to "always")');
|
||||
return;
|
||||
default: {
|
||||
// HACK: rewrite req.url so that sirv finds the file
|
||||
req.url = '/' + req.url?.replace(baseURL.pathname, '');
|
||||
staticFileServer(req, res, () => {
|
||||
const errorPagePath = fileURLToPath(settings.config.outDir + '/404.html');
|
||||
if (fs.existsSync(errorPagePath)) {
|
||||
res.statusCode = 404;
|
||||
res.setHeader('Content-Type', 'text/html;charset=utf-8');
|
||||
res.end(fs.readFileSync(errorPagePath));
|
||||
} else {
|
||||
staticFileServer(req, res, () => {
|
||||
sendError('Not Found');
|
||||
});
|
||||
}
|
||||
});
|
||||
return;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
let httpServer: http.Server;
|
||||
|
||||
/** Expose dev server to `port` */
|
||||
function startServer(timerStart: number): Promise<void> {
|
||||
let showedPortTakenMsg = false;
|
||||
let showedListenMsg = false;
|
||||
return new Promise<void>((resolve, reject) => {
|
||||
const listen = () => {
|
||||
httpServer = server.listen(port, host, async () => {
|
||||
if (!showedListenMsg) {
|
||||
const resolvedUrls = msg.resolveServerUrls({
|
||||
address: server.address() as AddressInfo,
|
||||
preview: {
|
||||
host: settings.config.server.host,
|
||||
https: false,
|
||||
port: settings.config.server.port,
|
||||
headers: settings.config.server.headers,
|
||||
},
|
||||
plugins: [vitePluginAstroPreview(settings)],
|
||||
});
|
||||
} catch (err) {
|
||||
if (err instanceof Error) {
|
||||
error(logging, 'astro', err.stack || err.message);
|
||||
}
|
||||
throw err;
|
||||
}
|
||||
|
||||
enableDestroy(previewServer.httpServer);
|
||||
|
||||
// Log server start URLs
|
||||
info(
|
||||
logging,
|
||||
null,
|
||||
msg.serverStart({
|
||||
startupTime: performance.now() - timerStart,
|
||||
resolvedUrls,
|
||||
startupTime: performance.now() - startServerTime,
|
||||
resolvedUrls: previewServer.resolvedUrls,
|
||||
host: settings.config.server.host,
|
||||
site: baseURL,
|
||||
base: settings.config.base,
|
||||
})
|
||||
);
|
||||
}
|
||||
showedListenMsg = true;
|
||||
resolve();
|
||||
});
|
||||
httpServer?.on('error', onError);
|
||||
};
|
||||
|
||||
const onError = (err: NodeJS.ErrnoException) => {
|
||||
if (err.code && err.code === 'EADDRINUSE') {
|
||||
if (!showedPortTakenMsg) {
|
||||
info(logging, 'astro', msg.portInUse({ port }));
|
||||
showedPortTakenMsg = true; // only print this once
|
||||
}
|
||||
port++;
|
||||
return listen(); // retry
|
||||
} else {
|
||||
error(logging, 'astro', err.stack || err.message);
|
||||
httpServer?.removeListener('error', onError);
|
||||
reject(err); // reject
|
||||
}
|
||||
};
|
||||
|
||||
listen();
|
||||
});
|
||||
}
|
||||
|
||||
// Start listening on `hostname:port`.
|
||||
await startServer(startServerTime);
|
||||
|
||||
// Resolves once the server is closed
|
||||
function closed() {
|
||||
return new Promise<void>((resolve, reject) => {
|
||||
httpServer!.addListener('close', resolve);
|
||||
httpServer!.addListener('error', reject);
|
||||
previewServer.httpServer.addListener('close', resolve);
|
||||
previewServer.httpServer.addListener('error', reject);
|
||||
});
|
||||
}
|
||||
|
||||
return {
|
||||
host,
|
||||
port,
|
||||
host: getResolvedHostForHttpServer(settings.config.server.host),
|
||||
port: settings.config.server.port,
|
||||
closed,
|
||||
server: httpServer!,
|
||||
server: previewServer.httpServer,
|
||||
stop: async () => {
|
||||
await new Promise((resolve, reject) => {
|
||||
httpServer.close((err) => (err ? reject(err) : resolve(undefined)));
|
||||
previewServer.httpServer.destroy((err) => (err ? reject(err) : resolve(undefined)));
|
||||
});
|
||||
},
|
||||
};
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
export function getResolvedHostForHttpServer(host: string | boolean) {
|
||||
if (host === false) {
|
||||
// Use a secure default
|
||||
return '127.0.0.1';
|
||||
return 'localhost';
|
||||
} else if (host === true) {
|
||||
// If passed --host in the CLI without arguments
|
||||
return undefined; // undefined typically means 0.0.0.0 or :: (listen on all IPs)
|
||||
|
@ -9,3 +9,11 @@ export function getResolvedHostForHttpServer(host: string | boolean) {
|
|||
return host;
|
||||
}
|
||||
}
|
||||
|
||||
export function stripBase(path: string, base: string): string {
|
||||
if (path === base) {
|
||||
return '/';
|
||||
}
|
||||
const baseWithSlash = base.endsWith('/') ? base : base + '/';
|
||||
return path.replace(RegExp('^' + baseWithSlash), '/');
|
||||
}
|
||||
|
|
68
packages/astro/src/core/preview/vite-plugin-astro-preview.ts
Normal file
68
packages/astro/src/core/preview/vite-plugin-astro-preview.ts
Normal file
|
@ -0,0 +1,68 @@
|
|||
import fs from 'fs';
|
||||
import { fileURLToPath } from 'url';
|
||||
import { Plugin } from 'vite';
|
||||
import { AstroSettings } from '../../@types/astro.js';
|
||||
import { notFoundTemplate, subpathNotUsedTemplate } from '../../template/4xx.js';
|
||||
import { stripBase } from './util.js';
|
||||
|
||||
const HAS_FILE_EXTENSION_REGEXP = /^.*\.[^\\]+$/;
|
||||
|
||||
export function vitePluginAstroPreview(settings: AstroSettings): Plugin {
|
||||
const { base, outDir, trailingSlash } = settings.config;
|
||||
|
||||
return {
|
||||
name: 'astro:preview',
|
||||
apply: 'serve',
|
||||
configurePreviewServer(server) {
|
||||
server.middlewares.use((req, res, next) => {
|
||||
// respond 404 to requests outside the base request directory
|
||||
if (!req.url!.startsWith(base)) {
|
||||
res.statusCode = 404;
|
||||
res.end(subpathNotUsedTemplate(base, req.url!));
|
||||
return;
|
||||
}
|
||||
|
||||
const pathname = stripBase(req.url!, base);
|
||||
const isRoot = pathname === '/';
|
||||
|
||||
// Validate trailingSlash
|
||||
if (!isRoot) {
|
||||
const hasTrailingSlash = pathname.endsWith('/');
|
||||
|
||||
if (hasTrailingSlash && trailingSlash == 'never') {
|
||||
res.statusCode = 404;
|
||||
res.end(notFoundTemplate(pathname, 'Not Found (trailingSlash is set to "never")'));
|
||||
return;
|
||||
}
|
||||
|
||||
if (
|
||||
!hasTrailingSlash &&
|
||||
trailingSlash == 'always' &&
|
||||
!HAS_FILE_EXTENSION_REGEXP.test(pathname)
|
||||
) {
|
||||
res.statusCode = 404;
|
||||
res.end(notFoundTemplate(pathname, 'Not Found (trailingSlash is set to "always")'));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
next();
|
||||
});
|
||||
|
||||
return () => {
|
||||
server.middlewares.use((req, res) => {
|
||||
const errorPagePath = fileURLToPath(outDir + '/404.html');
|
||||
if (fs.existsSync(errorPagePath)) {
|
||||
res.statusCode = 404;
|
||||
res.setHeader('Content-Type', 'text/html;charset=utf-8');
|
||||
res.end(fs.readFileSync(errorPagePath));
|
||||
} else {
|
||||
const pathname = stripBase(req.url!, base);
|
||||
res.statusCode = 404;
|
||||
res.end(notFoundTemplate(pathname, 'Not Found'));
|
||||
}
|
||||
});
|
||||
};
|
||||
},
|
||||
};
|
||||
}
|
|
@ -164,14 +164,6 @@ export function emoji(char: string, fallback: string) {
|
|||
return process.platform !== 'win32' ? char : fallback;
|
||||
}
|
||||
|
||||
export function getLocalAddress(serverAddress: string, host: string | boolean): string {
|
||||
if (typeof host === 'boolean' || host === 'localhost') {
|
||||
return 'localhost';
|
||||
} else {
|
||||
return serverAddress;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Simulate Vite's resolve and import analysis so we can import the id as an URL
|
||||
* through a script tag or a dynamic import as-is.
|
||||
|
|
|
@ -77,17 +77,11 @@ describe('astro cli', () => {
|
|||
const localURL = new URL(local);
|
||||
const networkURL = new URL(network);
|
||||
|
||||
if (cmd === 'dev') {
|
||||
expect(localURL.hostname).to.be.oneOf(
|
||||
['localhost', '127.0.0.1'],
|
||||
`Expected local URL to be on localhost`
|
||||
);
|
||||
} else {
|
||||
expect(localURL.hostname).to.be.equal(
|
||||
flagValue ?? 'localhost',
|
||||
`Expected local URL to be on localhost`
|
||||
);
|
||||
}
|
||||
|
||||
// Note: our tests run in parallel so this could be 3000+!
|
||||
expect(Number.parseInt(localURL.port)).to.be.greaterThanOrEqual(
|
||||
3000,
|
||||
|
@ -113,17 +107,11 @@ describe('astro cli', () => {
|
|||
expect(network).to.not.be.undefined;
|
||||
const localURL = new URL(local);
|
||||
|
||||
if (cmd === 'dev') {
|
||||
expect(localURL.hostname).to.be.oneOf(
|
||||
['localhost', '127.0.0.1'],
|
||||
`Expected local URL to be on localhost`
|
||||
);
|
||||
} else {
|
||||
expect(localURL.hostname).to.be.equal(
|
||||
'localhost',
|
||||
`Expected local URL to be on localhost`
|
||||
);
|
||||
}
|
||||
|
||||
expect(() => new URL(networkURL)).to.throw();
|
||||
});
|
||||
});
|
||||
|
@ -140,14 +128,10 @@ describe('astro cli', () => {
|
|||
expect(network).to.be.undefined;
|
||||
|
||||
const localURL = new URL(local);
|
||||
if (cmd === 'dev') {
|
||||
expect(localURL.hostname).to.be.oneOf(
|
||||
['localhost', '127.0.0.1'],
|
||||
`Expected local URL to be on localhost`
|
||||
);
|
||||
} else {
|
||||
expect(localURL.hostname).to.be.equal(flagValue, `Expected local URL to be on localhost`);
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -31,13 +31,13 @@
|
|||
"test:match": "playwright test -g"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@playwright/test": "^1.26.0",
|
||||
"@playwright/test": "^1.29.2",
|
||||
"@types/chai": "^4.3.1",
|
||||
"@types/chai-as-promised": "^7.1.5",
|
||||
"@types/mocha": "^9.1.1",
|
||||
"astro": "workspace:*",
|
||||
"astro-scripts": "workspace:*",
|
||||
"playwright": "^1.22.2"
|
||||
"playwright": "^1.29.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"throttles": "^1.0.1"
|
||||
|
|
|
@ -19,7 +19,7 @@ test.describe('Basic prefetch', () => {
|
|||
test('skips /admin', async ({ page, astro }) => {
|
||||
const requests = [];
|
||||
|
||||
page.on('request', async (request) => requests.push(request.url()));
|
||||
page.on('request', (request) => requests.push(request.url()));
|
||||
|
||||
await page.goto(astro.resolveUrl('/'));
|
||||
|
||||
|
@ -56,7 +56,7 @@ test.describe('Basic prefetch', () => {
|
|||
test('skips /admin', async ({ page, astro }) => {
|
||||
const requests = [];
|
||||
|
||||
page.on('request', async (request) => requests.push(request.url()));
|
||||
page.on('request', (request) => requests.push(request.url()));
|
||||
|
||||
await page.goto(astro.resolveUrl('/'));
|
||||
|
||||
|
|
|
@ -27,7 +27,7 @@ test.describe('Custom prefetch selectors', () => {
|
|||
test('only prefetches /contact', async ({ page, astro }) => {
|
||||
const requests = [];
|
||||
|
||||
page.on('request', async (request) => requests.push(request.url()));
|
||||
page.on('request', (request) => requests.push(request.url()));
|
||||
|
||||
await page.goto(astro.resolveUrl('/'));
|
||||
|
||||
|
@ -64,7 +64,7 @@ test.describe('Custom prefetch selectors', () => {
|
|||
test('only prefetches /contact', async ({ page, astro }) => {
|
||||
const requests = [];
|
||||
|
||||
page.on('request', async (request) => requests.push(request.url()));
|
||||
page.on('request', (request) => requests.push(request.url()));
|
||||
|
||||
await page.goto(astro.resolveUrl('/'));
|
||||
|
||||
|
|
|
@ -39,7 +39,7 @@ test.describe('Style prefetch', () => {
|
|||
test('style fetching', async ({ page, astro }) => {
|
||||
const requests = [];
|
||||
|
||||
page.on('request', async (request) => requests.push(request.url()));
|
||||
page.on('request', (request) => requests.push(request.url()));
|
||||
|
||||
await page.goto(astro.resolveUrl('/'));
|
||||
|
||||
|
|
|
@ -396,7 +396,7 @@ importers:
|
|||
'@babel/plugin-transform-react-jsx': ^7.17.12
|
||||
'@babel/traverse': ^7.18.2
|
||||
'@babel/types': ^7.18.4
|
||||
'@playwright/test': ^1.22.2
|
||||
'@playwright/test': ^1.29.2
|
||||
'@types/babel__core': ^7.1.19
|
||||
'@types/babel__generator': ^7.6.4
|
||||
'@types/babel__traverse': ^7.17.1
|
||||
|
@ -418,6 +418,7 @@ importers:
|
|||
'@types/resolve': ^1.20.2
|
||||
'@types/rimraf': ^3.0.2
|
||||
'@types/send': ^0.17.1
|
||||
'@types/server-destroy': ^1.0.1
|
||||
'@types/unist': ^2.0.6
|
||||
'@types/yargs-parser': ^21.0.0
|
||||
acorn: ^8.8.1
|
||||
|
@ -466,8 +467,8 @@ importers:
|
|||
rollup: ^3.9.0
|
||||
sass: ^1.52.2
|
||||
semver: ^7.3.7
|
||||
server-destroy: ^1.0.1
|
||||
shiki: ^0.11.1
|
||||
sirv: ^2.0.2
|
||||
slash: ^4.0.0
|
||||
srcset-parse: ^1.1.0
|
||||
string-width: ^5.1.2
|
||||
|
@ -529,8 +530,8 @@ importers:
|
|||
rehype: 12.0.1
|
||||
resolve: 1.22.1
|
||||
semver: 7.3.8
|
||||
server-destroy: 1.0.1
|
||||
shiki: 0.11.1
|
||||
sirv: 2.0.2
|
||||
slash: 4.0.0
|
||||
string-width: 5.1.2
|
||||
strip-ansi: 7.0.1
|
||||
|
@ -564,6 +565,7 @@ importers:
|
|||
'@types/resolve': 1.20.2
|
||||
'@types/rimraf': 3.0.2
|
||||
'@types/send': 0.17.1
|
||||
'@types/server-destroy': 1.0.1
|
||||
'@types/unist': 2.0.6
|
||||
astro-scripts: link:../../scripts
|
||||
chai: 4.3.7
|
||||
|
@ -3139,13 +3141,13 @@ importers:
|
|||
|
||||
packages/integrations/prefetch:
|
||||
specifiers:
|
||||
'@playwright/test': ^1.26.0
|
||||
'@playwright/test': ^1.29.2
|
||||
'@types/chai': ^4.3.1
|
||||
'@types/chai-as-promised': ^7.1.5
|
||||
'@types/mocha': ^9.1.1
|
||||
astro: workspace:*
|
||||
astro-scripts: workspace:*
|
||||
playwright: ^1.22.2
|
||||
playwright: ^1.29.2
|
||||
throttles: ^1.0.1
|
||||
dependencies:
|
||||
throttles: 1.0.1
|
||||
|
@ -7055,6 +7057,7 @@ packages:
|
|||
|
||||
/@types/node/14.18.36:
|
||||
resolution: {integrity: sha512-FXKWbsJ6a1hIrRxv+FoukuHnGTgEzKYGi7kilfMae96AL9UNkPFNWJEEYWzdRI9ooIkbr4AKldyuSTLql06vLQ==}
|
||||
dev: true
|
||||
|
||||
/@types/node/16.18.11:
|
||||
resolution: {integrity: sha512-3oJbGBUWuS6ahSnEq1eN2XrCyf4YsWI8OyCvo7c64zQJNplk3mO84t53o8lfTk+2ji59g5ycfc6qQ3fdHliHuA==}
|
||||
|
@ -7126,7 +7129,7 @@ packages:
|
|||
/@types/resolve/1.17.1:
|
||||
resolution: {integrity: sha512-yy7HuzQhj0dhGpD8RLXSZWEkLsV9ibvxvi6EiJ3bkqLAO1RGo0WbkWQiwpRlSFymTJRz0d3k5LM3kkx8ArDbLw==}
|
||||
dependencies:
|
||||
'@types/node': 14.18.36
|
||||
'@types/node': 18.11.18
|
||||
|
||||
/@types/resolve/1.20.2:
|
||||
resolution: {integrity: sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q==}
|
||||
|
@ -7141,7 +7144,7 @@ packages:
|
|||
/@types/sax/1.2.4:
|
||||
resolution: {integrity: sha512-pSAff4IAxJjfAXUG6tFkO7dsSbTmf8CtUpfhhZ5VhkRpC4628tJhh3+V6H1E+/Gs9piSzYKT5yzHO5M4GG9jkw==}
|
||||
dependencies:
|
||||
'@types/node': 17.0.45
|
||||
'@types/node': 18.11.18
|
||||
dev: false
|
||||
|
||||
/@types/scheduler/0.16.2:
|
||||
|
@ -7162,6 +7165,12 @@ packages:
|
|||
'@types/node': 18.11.18
|
||||
dev: true
|
||||
|
||||
/@types/server-destroy/1.0.1:
|
||||
resolution: {integrity: sha512-77QGr7waZbE0Y0uF+G+uH3H3SmhyA78Jf2r5r7QSrpg0U3kSXduWpGjzP9PvPLR/KCy+kHjjpnugRHsYTnHopg==}
|
||||
dependencies:
|
||||
'@types/node': 18.11.18
|
||||
dev: true
|
||||
|
||||
/@types/set-cookie-parser/2.4.2:
|
||||
resolution: {integrity: sha512-fBZgytwhYAUkj/jC/FAV4RQ5EerRup1YQsXQCh8rZfiHkc4UahC192oH0smGwsXol3cL3A5oETuAHeQHmhXM4w==}
|
||||
dependencies:
|
||||
|
@ -11129,7 +11138,7 @@ packages:
|
|||
resolution: {integrity: sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ==}
|
||||
engines: {node: '>= 10.13.0'}
|
||||
dependencies:
|
||||
'@types/node': 14.18.36
|
||||
'@types/node': 18.11.18
|
||||
merge-stream: 2.0.0
|
||||
supports-color: 7.2.0
|
||||
|
||||
|
@ -13994,6 +14003,10 @@ packages:
|
|||
randombytes: 2.1.0
|
||||
dev: true
|
||||
|
||||
/server-destroy/1.0.1:
|
||||
resolution: {integrity: sha512-rb+9B5YBIEzYcD6x2VKidaa+cqYBJQKnU4oe4E3ANwRRN56yk/ua1YCJT1n21NTS8w6CcOclAKNP3PhdCXKYtQ==}
|
||||
dev: false
|
||||
|
||||
/set-blocking/2.0.0:
|
||||
resolution: {integrity: sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==}
|
||||
|
||||
|
|
Loading…
Reference in a new issue