heroshot 0.16.0 → 0.17.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli/cli.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { C as intro, D as setVerbose, E as outro, O as spinner, S as error, T as note, _ as loadConfig, a as launchBrowser, c as generateSessionKey, d as loadSession, f as saveLocalKey, g as getConfigPath, h as ensureHeroshotDirectory, k as verbose, l as getSessionPath, m as sessionExists, n as snippetAction, o as DEFAULT_VIEWPORT, p as saveSession, r as sync, s as EDITOR_DIR, u as loadLocalKey, v as saveConfig, w as log, x as generateUid, y as VIEWPORT_PRESETS } from "../snippet-
|
|
2
|
+
import { C as intro, D as setVerbose, E as outro, O as spinner, S as error, T as note, _ as loadConfig, a as launchBrowser, c as generateSessionKey, d as loadSession, f as saveLocalKey, g as getConfigPath, h as ensureHeroshotDirectory, k as verbose, l as getSessionPath, m as sessionExists, n as snippetAction, o as DEFAULT_VIEWPORT, p as saveSession, r as sync, s as EDITOR_DIR, u as loadLocalKey, v as saveConfig, w as log, x as generateUid, y as VIEWPORT_PRESETS } from "../snippet-Cm6b-EdU.js";
|
|
3
3
|
import { existsSync, readFileSync, rmSync } from "node:fs";
|
|
4
4
|
import path from "node:path";
|
|
5
5
|
import { fileURLToPath } from "node:url";
|
package/dist/mcp/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { _ as loadConfig, b as screenshotSchema, g as getConfigPath, i as filterScreenshots, r as sync, t as generateSnippets, v as saveConfig, x as generateUid } from "../snippet-
|
|
2
|
+
import { _ as loadConfig, b as screenshotSchema, g as getConfigPath, i as filterScreenshots, r as sync, t as generateSnippets, v as saveConfig, x as generateUid } from "../snippet-Cm6b-EdU.js";
|
|
3
3
|
import { ZodOptional, z } from "zod";
|
|
4
4
|
import * as z3rt from "zod/v3";
|
|
5
5
|
import { ZodFirstPartyTypeKind } from "zod/v3";
|
|
@@ -371,7 +371,8 @@ const configSchema = z.object({
|
|
|
371
371
|
browser: browserSchema.optional().describe("Default browser settings applied to all screenshots"),
|
|
372
372
|
workers: z.number().int().min(1).optional().describe("Number of parallel capture workers (default: 1)"),
|
|
373
373
|
screenshots: z.array(screenshotSchema).default([]).describe("Screenshot definitions"),
|
|
374
|
-
hiddenElements: z.record(z.string(), z.array(z.string())).optional().describe("Elements to hide per domain (hostname → CSS selectors)")
|
|
374
|
+
hiddenElements: z.record(z.string(), z.array(z.string())).optional().describe("Elements to hide per domain (hostname → CSS selectors)"),
|
|
375
|
+
locales: z.array(z.string().min(1)).optional().describe("Locale codes (e.g., [\"en\", \"de\"]).")
|
|
375
376
|
});
|
|
376
377
|
|
|
377
378
|
//#endregion
|
|
@@ -731,7 +732,9 @@ async function launchBrowser(options = {}) {
|
|
|
731
732
|
...options.storageState && { storageState: options.storageState },
|
|
732
733
|
...options.colorScheme && { colorScheme: options.colorScheme },
|
|
733
734
|
...options.reducedMotion && { reducedMotion: options.reducedMotion },
|
|
734
|
-
...options.userAgent && { userAgent: options.userAgent }
|
|
735
|
+
...options.userAgent && { userAgent: options.userAgent },
|
|
736
|
+
...options.locale && { locale: options.locale },
|
|
737
|
+
...options.locale && { extraHTTPHeaders: { "Accept-Language": options.locale } }
|
|
735
738
|
});
|
|
736
739
|
return {
|
|
737
740
|
browser,
|
|
@@ -778,12 +781,13 @@ function resolveOutputDirectory(configPath, configOutputDirectory, override) {
|
|
|
778
781
|
/**
|
|
779
782
|
* Calculate total number of captures needed.
|
|
780
783
|
*/
|
|
781
|
-
function calculateTotalCaptures(screenshots, schemeCount) {
|
|
784
|
+
function calculateTotalCaptures(screenshots, schemeCount, localeCount = 1) {
|
|
782
785
|
let total = 0;
|
|
783
786
|
const adjustedSchemeCount = Math.max(1, schemeCount);
|
|
787
|
+
const adjustedLocaleCount = Math.max(1, localeCount);
|
|
784
788
|
for (const screenshot of screenshots) {
|
|
785
789
|
const viewportCount = screenshot.viewports?.length ?? 1;
|
|
786
|
-
total += viewportCount * adjustedSchemeCount;
|
|
790
|
+
total += viewportCount * adjustedSchemeCount * adjustedLocaleCount;
|
|
787
791
|
}
|
|
788
792
|
return total;
|
|
789
793
|
}
|
|
@@ -814,6 +818,23 @@ function buildBrowserOptions(config) {
|
|
|
814
818
|
};
|
|
815
819
|
}
|
|
816
820
|
|
|
821
|
+
//#endregion
|
|
822
|
+
//#region src/utils/localeUrl.ts
|
|
823
|
+
/**
|
|
824
|
+
* Apply locale to a URL by replacing the {locale} placeholder.
|
|
825
|
+
* If the URL contains no placeholder, it is returned unchanged.
|
|
826
|
+
*
|
|
827
|
+
* @example
|
|
828
|
+
* applyLocale('http://localhost:5173/{locale}/about', 'de')
|
|
829
|
+
* // → 'http://localhost:5173/de/about'
|
|
830
|
+
*
|
|
831
|
+
* applyLocale('http://localhost:5173/about', 'de')
|
|
832
|
+
* // → 'http://localhost:5173/about'
|
|
833
|
+
*/
|
|
834
|
+
function applyLocale(url, locale) {
|
|
835
|
+
return url.replaceAll("{locale}", locale);
|
|
836
|
+
}
|
|
837
|
+
|
|
817
838
|
//#endregion
|
|
818
839
|
//#region src/utils/parseViewport.ts
|
|
819
840
|
/**
|
|
@@ -861,7 +882,7 @@ function slugifySegment(text) {
|
|
|
861
882
|
* Supports subdirectory paths via forward slashes in the name (e.g., "registry/login-01").
|
|
862
883
|
*/
|
|
863
884
|
function generateScreenshotFilename(options) {
|
|
864
|
-
const { name, viewport, colorScheme, format = "png" } = options;
|
|
885
|
+
const { name, viewport, colorScheme, locale, format = "png" } = options;
|
|
865
886
|
const segments = name.split("/").map(slugifySegment).filter(Boolean);
|
|
866
887
|
const directory = segments.length > 1 ? segments.slice(0, -1).join("/") : "";
|
|
867
888
|
const parts = [segments.at(-1) ?? ""];
|
|
@@ -869,7 +890,8 @@ function generateScreenshotFilename(options) {
|
|
|
869
890
|
if (colorScheme) parts.push(colorScheme);
|
|
870
891
|
const extension = format === "jpeg" ? "jpg" : "png";
|
|
871
892
|
const filename = `${parts.join("-")}.${extension}`;
|
|
872
|
-
|
|
893
|
+
const pathWithDirectory = directory ? `${directory}/${filename}` : filename;
|
|
894
|
+
return locale ? `${locale}/${pathWithDirectory}` : pathWithDirectory;
|
|
873
895
|
}
|
|
874
896
|
|
|
875
897
|
//#endregion
|
|
@@ -1749,8 +1771,12 @@ async function captureElementScreenshot(options) {
|
|
|
1749
1771
|
/**
|
|
1750
1772
|
* Build a variant ID suffix.
|
|
1751
1773
|
*/
|
|
1752
|
-
function buildVariantSuffix(viewportName, colorScheme) {
|
|
1753
|
-
return [
|
|
1774
|
+
function buildVariantSuffix(viewportName, colorScheme, locale) {
|
|
1775
|
+
return [
|
|
1776
|
+
locale,
|
|
1777
|
+
viewportName,
|
|
1778
|
+
colorScheme
|
|
1779
|
+
].filter(Boolean).join("-");
|
|
1754
1780
|
}
|
|
1755
1781
|
/**
|
|
1756
1782
|
* Show capture results and return summary.
|
|
@@ -1854,18 +1880,20 @@ async function captureScreenshot(page, screenshot, outputDirectory, captureOptio
|
|
|
1854
1880
|
name,
|
|
1855
1881
|
viewport: variant.viewportName,
|
|
1856
1882
|
colorScheme: variant.colorScheme,
|
|
1883
|
+
locale: variant.locale,
|
|
1857
1884
|
format
|
|
1858
1885
|
});
|
|
1859
|
-
const suffix = buildVariantSuffix(variant.viewportName, variant.colorScheme);
|
|
1886
|
+
const suffix = buildVariantSuffix(variant.viewportName, variant.colorScheme, variant.locale);
|
|
1860
1887
|
verbose(`Capturing: ${name}${suffix ? ` (${suffix})` : ""}`);
|
|
1861
|
-
const
|
|
1888
|
+
const effectiveUrl = variant.localeUrl ?? url;
|
|
1889
|
+
const navResult = await navigateAndPrepare(page, effectiveUrl, variant.colorScheme);
|
|
1862
1890
|
if (!navResult.success) return {
|
|
1863
1891
|
...navResult,
|
|
1864
1892
|
filename
|
|
1865
1893
|
};
|
|
1866
1894
|
if (captureOptions.hiddenElements) {
|
|
1867
1895
|
const { hiddenElements: hiddenByDomain } = captureOptions;
|
|
1868
|
-
const { hostname } = new URL(
|
|
1896
|
+
const { hostname } = new URL(effectiveUrl);
|
|
1869
1897
|
if (hiddenByDomain[hostname]?.length) await executeHide(page, {
|
|
1870
1898
|
type: "hide",
|
|
1871
1899
|
selectors: hiddenByDomain[hostname]
|
|
@@ -1928,7 +1956,7 @@ async function captureAndLog(page, screenshot, outputDirectory, captureOptions,
|
|
|
1928
1956
|
await page.waitForTimeout(delay);
|
|
1929
1957
|
}
|
|
1930
1958
|
}
|
|
1931
|
-
const suffix = buildVariantSuffix(variant.viewportName, variant.colorScheme);
|
|
1959
|
+
const suffix = buildVariantSuffix(variant.viewportName, variant.colorScheme, variant.locale);
|
|
1932
1960
|
const displayName = suffix ? `${screenshot.name} (${suffix})` : screenshot.name;
|
|
1933
1961
|
const idSuffix = suffix ? `-${suffix}` : "";
|
|
1934
1962
|
return {
|
|
@@ -1946,31 +1974,41 @@ async function captureAndLog(page, screenshot, outputDirectory, captureOptions,
|
|
|
1946
1974
|
* Parallel screenshot capture with multiple workers.
|
|
1947
1975
|
*/
|
|
1948
1976
|
/**
|
|
1949
|
-
* Build capture jobs from screenshots and
|
|
1977
|
+
* Build capture jobs from screenshots, schemes, and locales.
|
|
1950
1978
|
* Each job represents a single screenshot capture task.
|
|
1951
1979
|
*/
|
|
1952
|
-
function buildCaptureJobs(screenshots, schemes) {
|
|
1980
|
+
function buildCaptureJobs(screenshots, schemes, locales = []) {
|
|
1953
1981
|
const jobs = [];
|
|
1954
1982
|
const hasMultipleSchemes = schemes.length > 1;
|
|
1955
1983
|
const schemesToCapture = schemes.length === 0 ? [void 0] : schemes;
|
|
1984
|
+
const localesToCapture = locales.length === 0 ? [void 0] : locales;
|
|
1956
1985
|
for (const screenshot of screenshots) {
|
|
1957
1986
|
const viewportVariants = screenshot.viewports ?? [];
|
|
1958
1987
|
const hasMultipleViewports = viewportVariants.length > 1;
|
|
1959
|
-
for (const
|
|
1960
|
-
screenshot,
|
|
1961
|
-
|
|
1962
|
-
hasMultipleSchemes,
|
|
1963
|
-
hasMultipleViewports: false
|
|
1964
|
-
});
|
|
1965
|
-
else for (const viewportVariant of viewportVariants) {
|
|
1966
|
-
const parsedViewport = parseViewport(viewportVariant);
|
|
1967
|
-
jobs.push({
|
|
1988
|
+
for (const locale of localesToCapture) {
|
|
1989
|
+
const localeUrl = locale && screenshot.url.includes("{locale}") ? applyLocale(screenshot.url, locale) : void 0;
|
|
1990
|
+
for (const scheme of schemesToCapture) if (viewportVariants.length === 0) jobs.push({
|
|
1968
1991
|
screenshot,
|
|
1969
1992
|
colorScheme: scheme,
|
|
1970
|
-
viewport: parsedViewport,
|
|
1971
1993
|
hasMultipleSchemes,
|
|
1972
|
-
hasMultipleViewports
|
|
1994
|
+
hasMultipleViewports: false,
|
|
1995
|
+
locale,
|
|
1996
|
+
locales,
|
|
1997
|
+
localeUrl
|
|
1973
1998
|
});
|
|
1999
|
+
else for (const viewportVariant of viewportVariants) {
|
|
2000
|
+
const parsedViewport = parseViewport(viewportVariant);
|
|
2001
|
+
jobs.push({
|
|
2002
|
+
screenshot,
|
|
2003
|
+
colorScheme: scheme,
|
|
2004
|
+
viewport: parsedViewport,
|
|
2005
|
+
hasMultipleSchemes,
|
|
2006
|
+
hasMultipleViewports,
|
|
2007
|
+
locale,
|
|
2008
|
+
locales,
|
|
2009
|
+
localeUrl
|
|
2010
|
+
});
|
|
2011
|
+
}
|
|
1974
2012
|
}
|
|
1975
2013
|
}
|
|
1976
2014
|
return jobs;
|
|
@@ -1987,12 +2025,13 @@ async function executeBatch(jobs, outputDirectory, captureOptions, browserOption
|
|
|
1987
2025
|
storageState: browserOptions.storageState,
|
|
1988
2026
|
bypassCSP: browserOptions.bypassCSP,
|
|
1989
2027
|
reducedMotion: browserOptions.reducedMotion,
|
|
1990
|
-
userAgent: browserOptions.userAgent
|
|
2028
|
+
userAgent: browserOptions.userAgent,
|
|
2029
|
+
locale: jobs[0]?.locale
|
|
1991
2030
|
});
|
|
1992
2031
|
const page = await context.newPage();
|
|
1993
2032
|
try {
|
|
1994
2033
|
for (const job of jobs) {
|
|
1995
|
-
const { screenshot, colorScheme, viewport, hasMultipleSchemes, hasMultipleViewports } = job;
|
|
2034
|
+
const { screenshot, colorScheme, viewport, hasMultipleSchemes, hasMultipleViewports, locale, locales } = job;
|
|
1996
2035
|
if (viewport) await page.setViewportSize({
|
|
1997
2036
|
width: viewport.width,
|
|
1998
2037
|
height: viewport.height
|
|
@@ -2000,7 +2039,9 @@ async function executeBatch(jobs, outputDirectory, captureOptions, browserOption
|
|
|
2000
2039
|
if (colorScheme) await page.emulateMedia({ colorScheme });
|
|
2001
2040
|
const result = await captureAndLog(page, screenshot, outputDirectory, captureOptions, {
|
|
2002
2041
|
viewportName: hasMultipleViewports ? viewport?.name : void 0,
|
|
2003
|
-
colorScheme: hasMultipleSchemes ? colorScheme : void 0
|
|
2042
|
+
colorScheme: hasMultipleSchemes ? colorScheme : void 0,
|
|
2043
|
+
locale: (locales ?? []).length > 1 ? locale : void 0,
|
|
2044
|
+
localeUrl: job.localeUrl
|
|
2004
2045
|
});
|
|
2005
2046
|
results.push(result);
|
|
2006
2047
|
onProgress(result);
|
|
@@ -2011,16 +2052,17 @@ async function executeBatch(jobs, outputDirectory, captureOptions, browserOption
|
|
|
2011
2052
|
return results;
|
|
2012
2053
|
}
|
|
2013
2054
|
/**
|
|
2014
|
-
* Group jobs by URL to minimize page navigations.
|
|
2015
|
-
* Jobs for the same URL are kept together.
|
|
2055
|
+
* Group jobs by effective URL + locale to minimize page navigations.
|
|
2056
|
+
* Jobs for the same URL AND same locale are kept together.
|
|
2057
|
+
* Locale is a browser context-level setting, so different locales must be separate groups.
|
|
2016
2058
|
*/
|
|
2017
2059
|
function groupJobsByUrl(jobs) {
|
|
2018
2060
|
const groups = /* @__PURE__ */ new Map();
|
|
2019
2061
|
for (const job of jobs) {
|
|
2020
|
-
const
|
|
2021
|
-
const group = groups.get(
|
|
2062
|
+
const key = `${job.localeUrl ?? job.screenshot.url}::${job.locale ?? ""}`;
|
|
2063
|
+
const group = groups.get(key) ?? [];
|
|
2022
2064
|
group.push(job);
|
|
2023
|
-
groups.set(
|
|
2065
|
+
groups.set(key, group);
|
|
2024
2066
|
}
|
|
2025
2067
|
return groups;
|
|
2026
2068
|
}
|
|
@@ -2065,11 +2107,15 @@ async function captureParallel(options) {
|
|
|
2065
2107
|
//#endregion
|
|
2066
2108
|
//#region src/sync/schemeCapture.ts
|
|
2067
2109
|
/**
|
|
2068
|
-
* Capture screenshots for a single color scheme.
|
|
2110
|
+
* Capture screenshots for a single color scheme + locale combination.
|
|
2069
2111
|
* Launches a browser, captures all screenshots, and closes the browser.
|
|
2112
|
+
*
|
|
2113
|
+
* Locale is a browser context-level setting in Playwright, so each locale
|
|
2114
|
+
* gets its own browser launch. This ensures Accept-Language and JS locale APIs
|
|
2115
|
+
* (Intl, navigator.language) reflect the correct locale for all pages captured.
|
|
2070
2116
|
*/
|
|
2071
2117
|
async function captureWithScheme(options) {
|
|
2072
|
-
const { screenshots, outputDirectory, captureOptions, browserOptions, colorScheme, schemes, captureSpinner, progress } = options;
|
|
2118
|
+
const { screenshots, outputDirectory, captureOptions, browserOptions, colorScheme, schemes, locale, locales, captureSpinner, progress } = options;
|
|
2073
2119
|
const results = [];
|
|
2074
2120
|
const { browser, context } = await launchBrowser({
|
|
2075
2121
|
headless: !browserOptions.headed,
|
|
@@ -2079,22 +2125,32 @@ async function captureWithScheme(options) {
|
|
|
2079
2125
|
colorScheme,
|
|
2080
2126
|
bypassCSP: browserOptions.bypassCSP,
|
|
2081
2127
|
reducedMotion: browserOptions.reducedMotion,
|
|
2082
|
-
userAgent: browserOptions.userAgent
|
|
2128
|
+
userAgent: browserOptions.userAgent,
|
|
2129
|
+
locale
|
|
2083
2130
|
});
|
|
2084
2131
|
const page = await context.newPage();
|
|
2085
2132
|
if (colorScheme) await page.emulateMedia({ colorScheme });
|
|
2086
2133
|
const hasMultipleSchemes = schemes.length > 1;
|
|
2134
|
+
const hasMultipleLocales = locales.length > 1;
|
|
2087
2135
|
for (const screenshot of screenshots) {
|
|
2088
2136
|
const viewportVariants = screenshot.viewports ?? [];
|
|
2089
2137
|
const hasMultipleViewports = viewportVariants.length > 1;
|
|
2138
|
+
const localeUrl = locale && screenshot.url.includes("{locale}") ? applyLocale(screenshot.url, locale) : void 0;
|
|
2090
2139
|
if (viewportVariants.length === 0) {
|
|
2091
2140
|
progress.captured++;
|
|
2092
|
-
const variant = {
|
|
2093
|
-
|
|
2094
|
-
|
|
2141
|
+
const variant = {
|
|
2142
|
+
colorScheme: hasMultipleSchemes ? colorScheme : void 0,
|
|
2143
|
+
locale: hasMultipleLocales ? locale : void 0,
|
|
2144
|
+
localeUrl
|
|
2145
|
+
};
|
|
2146
|
+
const suffix = [variant.locale, variant.colorScheme].filter(Boolean).join(", ");
|
|
2147
|
+
const suffixDisplay = suffix ? ` (${suffix})` : "";
|
|
2148
|
+
captureSpinner.message(`Capturing ${progress.captured}/${progress.total}: ${screenshot.name}${suffixDisplay}`);
|
|
2095
2149
|
const result = await captureAndLog(page, screenshot, outputDirectory, captureOptions, variant);
|
|
2096
2150
|
results.push(result);
|
|
2097
|
-
|
|
2151
|
+
continue;
|
|
2152
|
+
}
|
|
2153
|
+
for (const viewportVariant of viewportVariants) {
|
|
2098
2154
|
const parsedViewport = parseViewport(viewportVariant);
|
|
2099
2155
|
await page.setViewportSize({
|
|
2100
2156
|
width: parsedViewport.width,
|
|
@@ -2103,9 +2159,15 @@ async function captureWithScheme(options) {
|
|
|
2103
2159
|
progress.captured++;
|
|
2104
2160
|
const variant = {
|
|
2105
2161
|
viewportName: hasMultipleViewports ? parsedViewport.name : void 0,
|
|
2106
|
-
colorScheme: hasMultipleSchemes ? colorScheme : void 0
|
|
2162
|
+
colorScheme: hasMultipleSchemes ? colorScheme : void 0,
|
|
2163
|
+
locale: hasMultipleLocales ? locale : void 0,
|
|
2164
|
+
localeUrl
|
|
2107
2165
|
};
|
|
2108
|
-
const suffix = [
|
|
2166
|
+
const suffix = [
|
|
2167
|
+
variant.locale,
|
|
2168
|
+
variant.viewportName,
|
|
2169
|
+
variant.colorScheme
|
|
2170
|
+
].filter(Boolean).join(", ");
|
|
2109
2171
|
const suffixDisplay = suffix ? ` (${suffix})` : "";
|
|
2110
2172
|
captureSpinner.message(`Capturing ${progress.captured}/${progress.total}: ${screenshot.name}${suffixDisplay}`);
|
|
2111
2173
|
const result = await captureAndLog(page, screenshot, outputDirectory, captureOptions, variant);
|
|
@@ -2204,9 +2266,9 @@ function handleStaleFiles(outputDirectory, results, options) {
|
|
|
2204
2266
|
* Execute screenshot capture (parallel or sequential based on workers).
|
|
2205
2267
|
*/
|
|
2206
2268
|
async function executeCapture(context) {
|
|
2207
|
-
const { screenshots, outputDirectory, captureOptions, browserOptions, schemes, workers, captureSpinner, progress } = context;
|
|
2269
|
+
const { screenshots, outputDirectory, captureOptions, browserOptions, schemes, locales, workers, captureSpinner, progress } = context;
|
|
2208
2270
|
if (workers > 1) return captureParallel({
|
|
2209
|
-
jobs: buildCaptureJobs(screenshots, schemes),
|
|
2271
|
+
jobs: buildCaptureJobs(screenshots, schemes, locales),
|
|
2210
2272
|
outputDirectory,
|
|
2211
2273
|
captureOptions,
|
|
2212
2274
|
browserOptions,
|
|
@@ -2216,7 +2278,8 @@ async function executeCapture(context) {
|
|
|
2216
2278
|
});
|
|
2217
2279
|
const results = [];
|
|
2218
2280
|
const schemesToCapture = schemes.length === 0 ? [void 0] : schemes;
|
|
2219
|
-
|
|
2281
|
+
const localesToCapture = locales.length === 0 ? [void 0] : locales;
|
|
2282
|
+
for (const locale of localesToCapture) for (const colorScheme of schemesToCapture) {
|
|
2220
2283
|
const schemeResults = await captureWithScheme({
|
|
2221
2284
|
screenshots,
|
|
2222
2285
|
outputDirectory,
|
|
@@ -2224,6 +2287,8 @@ async function executeCapture(context) {
|
|
|
2224
2287
|
browserOptions,
|
|
2225
2288
|
colorScheme,
|
|
2226
2289
|
schemes,
|
|
2290
|
+
locale,
|
|
2291
|
+
locales,
|
|
2227
2292
|
captureSpinner,
|
|
2228
2293
|
progress
|
|
2229
2294
|
});
|
|
@@ -2265,8 +2330,9 @@ async function sync(options = {}) {
|
|
|
2265
2330
|
const outputDirectory = resolveOutputDirectory(configPath, config.outputDirectory, options.outputDirectory);
|
|
2266
2331
|
const storageState = loadEncryptedSession(options.sessionKey);
|
|
2267
2332
|
const schemes = getColorSchemes(config.browser?.colorScheme);
|
|
2333
|
+
const locales = config.locales ?? [];
|
|
2268
2334
|
const captureOptions = buildCaptureOptions(config, options.viewportOnly);
|
|
2269
|
-
const totalToCapture = calculateTotalCaptures(screenshots, schemes.length);
|
|
2335
|
+
const totalToCapture = calculateTotalCaptures(screenshots, schemes.length, Math.max(1, locales.length));
|
|
2270
2336
|
const browserOptions = {
|
|
2271
2337
|
...buildBrowserOptions(config),
|
|
2272
2338
|
storageState,
|
|
@@ -2284,6 +2350,7 @@ async function sync(options = {}) {
|
|
|
2284
2350
|
captureOptions,
|
|
2285
2351
|
browserOptions,
|
|
2286
2352
|
schemes,
|
|
2353
|
+
locales,
|
|
2287
2354
|
workers,
|
|
2288
2355
|
captureSpinner,
|
|
2289
2356
|
progress: {
|