staklink 0.3.25 → 0.3.26
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/proxy-server.cjs
CHANGED
|
@@ -34824,7 +34824,7 @@ var SSEManager = class {
|
|
|
34824
34824
|
var sseManager = new SSEManager();
|
|
34825
34825
|
|
|
34826
34826
|
// src/proxy/version.ts
|
|
34827
|
-
var VERSION = "0.3.
|
|
34827
|
+
var VERSION = "0.3.26";
|
|
34828
34828
|
|
|
34829
34829
|
// node_modules/uuid/dist/esm/stringify.js
|
|
34830
34830
|
var byteToHex = [];
|
|
@@ -80756,6 +80756,189 @@ Stderr: ${error82.stderr}`
|
|
|
80756
80756
|
// src/proxy/playwright.ts
|
|
80757
80757
|
var fs10 = __toESM(require("fs/promises"), 1);
|
|
80758
80758
|
var path9 = __toESM(require("path"), 1);
|
|
80759
|
+
var DEFAULT_CONFIG = `import { defineConfig } from "@playwright/test";
|
|
80760
|
+
export default defineConfig({
|
|
80761
|
+
timeout: 60000,
|
|
80762
|
+
workers: 1,
|
|
80763
|
+
fullyParallel: false,
|
|
80764
|
+
reporter: [
|
|
80765
|
+
["list"],
|
|
80766
|
+
["./timestamp-reporter.ts"],
|
|
80767
|
+
],
|
|
80768
|
+
use: {
|
|
80769
|
+
video: "on",
|
|
80770
|
+
headless: true,
|
|
80771
|
+
browserName: "chromium",
|
|
80772
|
+
trace: "on-first-retry",
|
|
80773
|
+
},
|
|
80774
|
+
});
|
|
80775
|
+
`;
|
|
80776
|
+
var TIMESTAMP_REPORTER_CODE = `import {
|
|
80777
|
+
Reporter,
|
|
80778
|
+
TestCase,
|
|
80779
|
+
TestResult,
|
|
80780
|
+
TestStep,
|
|
80781
|
+
FullConfig,
|
|
80782
|
+
Suite,
|
|
80783
|
+
FullResult,
|
|
80784
|
+
} from "@playwright/test/reporter";
|
|
80785
|
+
import * as fs from "fs";
|
|
80786
|
+
import * as path from "path";
|
|
80787
|
+
|
|
80788
|
+
interface TimestampEntry {
|
|
80789
|
+
title: string;
|
|
80790
|
+
category: string;
|
|
80791
|
+
timestamp: string;
|
|
80792
|
+
relativeMs: number;
|
|
80793
|
+
duration: number;
|
|
80794
|
+
location: {
|
|
80795
|
+
file: string;
|
|
80796
|
+
line: number;
|
|
80797
|
+
column: number;
|
|
80798
|
+
};
|
|
80799
|
+
stepPath: string[];
|
|
80800
|
+
sourceCode?: string;
|
|
80801
|
+
error?: {
|
|
80802
|
+
message: string;
|
|
80803
|
+
stack?: string;
|
|
80804
|
+
};
|
|
80805
|
+
}
|
|
80806
|
+
|
|
80807
|
+
class TimestampReporter implements Reporter {
|
|
80808
|
+
private logs: TimestampEntry[] = [];
|
|
80809
|
+
private testStartTime: number = 0;
|
|
80810
|
+
private outputDir: string = "test-results";
|
|
80811
|
+
private sourceCache: Map<string, string[]> = new Map();
|
|
80812
|
+
|
|
80813
|
+
onBegin(config: FullConfig, suite: Suite) {
|
|
80814
|
+
this.outputDir = config.projects[0]?.outputDir || "test-results";
|
|
80815
|
+
console.log("\\n\u{1F3AC} Timestamp Reporter: Recording action timestamps\\n");
|
|
80816
|
+
}
|
|
80817
|
+
|
|
80818
|
+
private readSourceLine(filePath: string, lineNumber: number): string | undefined {
|
|
80819
|
+
try {
|
|
80820
|
+
// Check cache first
|
|
80821
|
+
if (!this.sourceCache.has(filePath)) {
|
|
80822
|
+
const content = fs.readFileSync(filePath, "utf-8");
|
|
80823
|
+
this.sourceCache.set(filePath, content.split("\\n"));
|
|
80824
|
+
}
|
|
80825
|
+
|
|
80826
|
+
const lines = this.sourceCache.get(filePath);
|
|
80827
|
+
if (lines && lineNumber > 0 && lineNumber <= lines.length) {
|
|
80828
|
+
return lines[lineNumber - 1].trim();
|
|
80829
|
+
}
|
|
80830
|
+
} catch (error) {
|
|
80831
|
+
console.error(\`Error reading source file \${filePath}:\`, error);
|
|
80832
|
+
}
|
|
80833
|
+
return undefined;
|
|
80834
|
+
}
|
|
80835
|
+
|
|
80836
|
+
onTestBegin(test: TestCase, result: TestResult) {
|
|
80837
|
+
this.testStartTime = Date.now();
|
|
80838
|
+
console.log(\`\\n\u{1F4DD} [\${new Date().toISOString()}] Test started: \${test.title}\`);
|
|
80839
|
+
}
|
|
80840
|
+
|
|
80841
|
+
onStepBegin(test: TestCase, result: TestResult, step: TestStep) {
|
|
80842
|
+
// Only log steps that have a location (actual test code)
|
|
80843
|
+
if (!step.location) return;
|
|
80844
|
+
|
|
80845
|
+
const timestamp = new Date().toISOString();
|
|
80846
|
+
const relativeMs = Date.now() - this.testStartTime;
|
|
80847
|
+
const indent = " ".repeat(step.titlePath().length - 1);
|
|
80848
|
+
const sourceCode = this.readSourceLine(step.location.file, step.location.line);
|
|
80849
|
+
|
|
80850
|
+
console.log(
|
|
80851
|
+
\`\${indent}\u23F1\uFE0F [\${timestamp}] +\${relativeMs}ms - \${sourceCode || step.title}\`
|
|
80852
|
+
);
|
|
80853
|
+
}
|
|
80854
|
+
|
|
80855
|
+
onStepEnd(test: TestCase, result: TestResult, step: TestStep) {
|
|
80856
|
+
// Only log steps that have a location (actual test code)
|
|
80857
|
+
if (!step.location) return;
|
|
80858
|
+
|
|
80859
|
+
const timestamp = new Date().toISOString();
|
|
80860
|
+
const relativeMs = Date.now() - this.testStartTime;
|
|
80861
|
+
|
|
80862
|
+
// Read the actual source code line
|
|
80863
|
+
const sourceCode = this.readSourceLine(step.location.file, step.location.line);
|
|
80864
|
+
|
|
80865
|
+
const entry: TimestampEntry = {
|
|
80866
|
+
title: step.title,
|
|
80867
|
+
category: step.category,
|
|
80868
|
+
timestamp: timestamp,
|
|
80869
|
+
relativeMs: relativeMs,
|
|
80870
|
+
duration: step.duration,
|
|
80871
|
+
stepPath: step.titlePath(),
|
|
80872
|
+
location: {
|
|
80873
|
+
file: step.location.file,
|
|
80874
|
+
line: step.location.line,
|
|
80875
|
+
column: step.location.column,
|
|
80876
|
+
},
|
|
80877
|
+
sourceCode: sourceCode,
|
|
80878
|
+
};
|
|
80879
|
+
|
|
80880
|
+
// Add error if present
|
|
80881
|
+
if (step.error) {
|
|
80882
|
+
entry.error = {
|
|
80883
|
+
message: step.error.message || "Unknown error",
|
|
80884
|
+
stack: step.error.stack,
|
|
80885
|
+
};
|
|
80886
|
+
}
|
|
80887
|
+
|
|
80888
|
+
this.logs.push(entry);
|
|
80889
|
+
|
|
80890
|
+
const indent = " ".repeat(step.titlePath().length - 1);
|
|
80891
|
+
const status = step.error ? "\u274C" : "\u2705";
|
|
80892
|
+
console.log(
|
|
80893
|
+
\`\${indent}\${status} [\${timestamp}] \${sourceCode || step.title} (\${step.duration}ms)\`
|
|
80894
|
+
);
|
|
80895
|
+
}
|
|
80896
|
+
|
|
80897
|
+
onTestEnd(test: TestCase, result: TestResult) {
|
|
80898
|
+
const videoAttachment = result.attachments.find((a) => a.name === "video");
|
|
80899
|
+
const videoPath = videoAttachment?.path;
|
|
80900
|
+
|
|
80901
|
+
const output = {
|
|
80902
|
+
testTitle: test.title,
|
|
80903
|
+
testId: test.id,
|
|
80904
|
+
status: result.status,
|
|
80905
|
+
duration: result.duration,
|
|
80906
|
+
startTime: new Date(this.testStartTime).toISOString(),
|
|
80907
|
+
videoPath: videoPath || null,
|
|
80908
|
+
actions: this.logs,
|
|
80909
|
+
};
|
|
80910
|
+
|
|
80911
|
+
// Write to test-results directory
|
|
80912
|
+
const sanitizedTitle = test.title
|
|
80913
|
+
.replace(/[^a-z0-9]/gi, "-")
|
|
80914
|
+
.toLowerCase();
|
|
80915
|
+
const outputPath = path.join(
|
|
80916
|
+
this.outputDir,
|
|
80917
|
+
\`timestamps-\${sanitizedTitle}.json\`
|
|
80918
|
+
);
|
|
80919
|
+
|
|
80920
|
+
fs.mkdirSync(path.dirname(outputPath), { recursive: true });
|
|
80921
|
+
fs.writeFileSync(outputPath, JSON.stringify(output, null, 2));
|
|
80922
|
+
|
|
80923
|
+
console.log(\`\\n\u{1F4BE} Timestamps saved to: \${outputPath}\`);
|
|
80924
|
+
if (videoPath) {
|
|
80925
|
+
console.log(\`\u{1F4F9} Video path: \${videoPath}\`);
|
|
80926
|
+
}
|
|
80927
|
+
console.log("");
|
|
80928
|
+
|
|
80929
|
+
// Reset logs for next test
|
|
80930
|
+
this.logs = [];
|
|
80931
|
+
// Clear source cache to free memory
|
|
80932
|
+
this.sourceCache.clear();
|
|
80933
|
+
}
|
|
80934
|
+
|
|
80935
|
+
onEnd(result: FullResult) {
|
|
80936
|
+
console.log(\`\\n\u2705 Test run complete! Status: \${result.status}\\n\`);
|
|
80937
|
+
}
|
|
80938
|
+
}
|
|
80939
|
+
|
|
80940
|
+
export default TimestampReporter;
|
|
80941
|
+
`;
|
|
80759
80942
|
async function findRepositoryLocation(repoName) {
|
|
80760
80943
|
const repoLocation = await findRepoLocation(repoName);
|
|
80761
80944
|
if (!repoLocation) {
|
|
@@ -80790,12 +80973,39 @@ async function findPlaywrightConfig(repoLocation) {
|
|
|
80790
80973
|
}
|
|
80791
80974
|
async function createPlaywrightConfig(repoLocation) {
|
|
80792
80975
|
const configPath = path9.join(repoLocation, "playwright.config.ts");
|
|
80793
|
-
|
|
80976
|
+
await fs10.writeFile(configPath, DEFAULT_CONFIG);
|
|
80977
|
+
console.log(`Created playwright config at ${configPath}`);
|
|
80978
|
+
return configPath;
|
|
80979
|
+
}
|
|
80980
|
+
async function createTimestampReporter(repoLocation) {
|
|
80981
|
+
const reporterPath = path9.join(repoLocation, "timestamp-reporter.ts");
|
|
80982
|
+
await fs10.writeFile(reporterPath, TIMESTAMP_REPORTER_CODE);
|
|
80983
|
+
console.log(`Created timestamp reporter at ${reporterPath}`);
|
|
80984
|
+
return reporterPath;
|
|
80985
|
+
}
|
|
80986
|
+
async function setupPlaywrightConfig(repoLocation) {
|
|
80987
|
+
let configPath = await findPlaywrightConfig(repoLocation);
|
|
80988
|
+
let wasCreated = false;
|
|
80989
|
+
let originalContent = null;
|
|
80990
|
+
let wasModified = false;
|
|
80991
|
+
const reporterPath = await createTimestampReporter(repoLocation);
|
|
80992
|
+
if (!configPath) {
|
|
80993
|
+
configPath = await createPlaywrightConfig(repoLocation);
|
|
80994
|
+
wasCreated = true;
|
|
80995
|
+
console.log("Created new playwright config");
|
|
80996
|
+
} else {
|
|
80997
|
+
originalContent = await fs10.readFile(configPath, "utf-8");
|
|
80998
|
+
wasModified = true;
|
|
80999
|
+
const newConfig = `import { defineConfig } from "@playwright/test";
|
|
80794
81000
|
|
|
80795
81001
|
export default defineConfig({
|
|
80796
81002
|
timeout: 60000,
|
|
80797
81003
|
workers: 1,
|
|
80798
81004
|
fullyParallel: false,
|
|
81005
|
+
reporter: [
|
|
81006
|
+
["list"],
|
|
81007
|
+
["./timestamp-reporter.ts"],
|
|
81008
|
+
],
|
|
80799
81009
|
use: {
|
|
80800
81010
|
video: "on",
|
|
80801
81011
|
headless: true,
|
|
@@ -80804,63 +81014,18 @@ export default defineConfig({
|
|
|
80804
81014
|
},
|
|
80805
81015
|
});
|
|
80806
81016
|
`;
|
|
80807
|
-
|
|
80808
|
-
|
|
80809
|
-
|
|
80810
|
-
}
|
|
80811
|
-
async function ensureVideoEnabled(configPath) {
|
|
80812
|
-
const configContent = await fs10.readFile(configPath, "utf-8");
|
|
80813
|
-
if (configContent.match(/video:\s*["']on["']/)) {
|
|
80814
|
-
console.log("Video already enabled in config");
|
|
80815
|
-
return null;
|
|
80816
|
-
}
|
|
80817
|
-
console.log("Updating config to enable video recording");
|
|
80818
|
-
let updatedConfig = configContent;
|
|
80819
|
-
const useBlockRegex = /use:\s*\{([^}]*)\}/s;
|
|
80820
|
-
const match2 = configContent.match(useBlockRegex);
|
|
80821
|
-
if (match2) {
|
|
80822
|
-
const useBlockContent = match2[1];
|
|
80823
|
-
if (useBlockContent.includes("video:")) {
|
|
80824
|
-
updatedConfig = configContent.replace(
|
|
80825
|
-
/video:\s*["'][^"']*["']/,
|
|
80826
|
-
'video: "on"'
|
|
80827
|
-
);
|
|
80828
|
-
} else {
|
|
80829
|
-
const updatedUseBlock = `use: {
|
|
80830
|
-
video: "on",${useBlockContent}}`;
|
|
80831
|
-
updatedConfig = configContent.replace(useBlockRegex, updatedUseBlock);
|
|
80832
|
-
}
|
|
80833
|
-
} else {
|
|
80834
|
-
const configObjectRegex = /export\s+default\s+defineConfig\(\s*\{/;
|
|
80835
|
-
updatedConfig = configContent.replace(
|
|
80836
|
-
configObjectRegex,
|
|
80837
|
-
`export default defineConfig({
|
|
80838
|
-
use: {
|
|
80839
|
-
video: "on",
|
|
80840
|
-
},`
|
|
81017
|
+
await fs10.writeFile(configPath, newConfig);
|
|
81018
|
+
console.log(
|
|
81019
|
+
`Overwrote existing config at ${configPath} (backed up for cleanup)`
|
|
80841
81020
|
);
|
|
80842
81021
|
}
|
|
80843
|
-
await fs10.writeFile(configPath, updatedConfig);
|
|
80844
|
-
console.log("Config updated to enable video recording");
|
|
80845
|
-
return configContent;
|
|
80846
|
-
}
|
|
80847
|
-
async function setupPlaywrightConfig(repoLocation) {
|
|
80848
|
-
let configPath = await findPlaywrightConfig(repoLocation);
|
|
80849
|
-
let wasCreated = false;
|
|
80850
|
-
let originalContent = null;
|
|
80851
|
-
let wasModified = false;
|
|
80852
|
-
if (!configPath) {
|
|
80853
|
-
configPath = await createPlaywrightConfig(repoLocation);
|
|
80854
|
-
wasCreated = true;
|
|
80855
|
-
} else {
|
|
80856
|
-
originalContent = await ensureVideoEnabled(configPath);
|
|
80857
|
-
wasModified = originalContent !== null;
|
|
80858
|
-
}
|
|
80859
81022
|
return {
|
|
80860
81023
|
configPath,
|
|
80861
81024
|
wasCreated,
|
|
80862
81025
|
originalContent,
|
|
80863
|
-
wasModified
|
|
81026
|
+
wasModified,
|
|
81027
|
+
reporterPath,
|
|
81028
|
+
reporterWasCreated: true
|
|
80864
81029
|
};
|
|
80865
81030
|
}
|
|
80866
81031
|
async function ensureTestResultsInGitignore(repoLocation) {
|
|
@@ -80933,14 +81098,48 @@ async function findVideoFile(repoLocation) {
|
|
|
80933
81098
|
console.log(`Found video at: ${videoPath}`);
|
|
80934
81099
|
return videoPath;
|
|
80935
81100
|
}
|
|
80936
|
-
async function
|
|
81101
|
+
async function findTimestampJsonFile(repoLocation) {
|
|
81102
|
+
const testResultsDir = path9.join(repoLocation, "test-results");
|
|
81103
|
+
const walkDir = async (dir) => {
|
|
81104
|
+
try {
|
|
81105
|
+
const files = await fs10.readdir(dir);
|
|
81106
|
+
for (const file3 of files) {
|
|
81107
|
+
const fullPath = path9.join(dir, file3);
|
|
81108
|
+
const stat4 = await fs10.stat(fullPath);
|
|
81109
|
+
if (stat4.isDirectory()) {
|
|
81110
|
+
const result = await walkDir(fullPath);
|
|
81111
|
+
if (result) {
|
|
81112
|
+
return result;
|
|
81113
|
+
}
|
|
81114
|
+
} else if (file3.startsWith("timestamps-") && file3.endsWith(".json")) {
|
|
81115
|
+
return fullPath;
|
|
81116
|
+
}
|
|
81117
|
+
}
|
|
81118
|
+
} catch (error82) {
|
|
81119
|
+
console.error(`Error walking directory ${dir}:`, error82);
|
|
81120
|
+
}
|
|
81121
|
+
return null;
|
|
81122
|
+
};
|
|
81123
|
+
const jsonPath = await walkDir(testResultsDir);
|
|
81124
|
+
if (!jsonPath) {
|
|
81125
|
+
throw new Error("No timestamp JSON file found in test-results directory");
|
|
81126
|
+
}
|
|
81127
|
+
console.log(`Found timestamp JSON at: ${jsonPath}`);
|
|
81128
|
+
return jsonPath;
|
|
81129
|
+
}
|
|
81130
|
+
async function uploadVideo(videoPath, timestampJsonPath, responseUrl) {
|
|
80937
81131
|
const videoBuffer = await fs10.readFile(videoPath);
|
|
81132
|
+
const jsonBuffer = await fs10.readFile(timestampJsonPath);
|
|
80938
81133
|
const FormData2 = (await Promise.resolve().then(() => __toESM(require_form_data(), 1))).default;
|
|
80939
81134
|
const formData = new FormData2();
|
|
80940
81135
|
formData.append("video", videoBuffer, {
|
|
80941
81136
|
filename: path9.basename(videoPath),
|
|
80942
81137
|
contentType: "video/webm"
|
|
80943
81138
|
});
|
|
81139
|
+
formData.append("timestamps", jsonBuffer, {
|
|
81140
|
+
filename: path9.basename(timestampJsonPath),
|
|
81141
|
+
contentType: "application/json"
|
|
81142
|
+
});
|
|
80944
81143
|
const uploadResponse = await fetch(responseUrl, {
|
|
80945
81144
|
method: "POST",
|
|
80946
81145
|
body: formData,
|
|
@@ -80948,34 +81147,49 @@ async function uploadVideo(videoPath, responseUrl) {
|
|
|
80948
81147
|
});
|
|
80949
81148
|
if (!uploadResponse.ok) {
|
|
80950
81149
|
throw new Error(
|
|
80951
|
-
`Failed to upload
|
|
81150
|
+
`Failed to upload files: ${uploadResponse.status} ${uploadResponse.statusText}`
|
|
80952
81151
|
);
|
|
80953
81152
|
}
|
|
80954
|
-
console.log(`Video uploaded successfully to ${responseUrl}`);
|
|
81153
|
+
console.log(`Video and timestamps uploaded successfully to ${responseUrl}`);
|
|
80955
81154
|
return uploadResponse.status;
|
|
80956
81155
|
}
|
|
80957
|
-
async function
|
|
81156
|
+
async function deleteTestFiles(videoPath, timestampJsonPath) {
|
|
80958
81157
|
try {
|
|
80959
81158
|
await fs10.unlink(videoPath);
|
|
80960
81159
|
console.log(`Deleted video file: ${videoPath}`);
|
|
80961
81160
|
} catch (error82) {
|
|
80962
81161
|
console.error(`Error deleting video file ${videoPath}:`, error82);
|
|
80963
81162
|
}
|
|
81163
|
+
try {
|
|
81164
|
+
await fs10.unlink(timestampJsonPath);
|
|
81165
|
+
console.log(`Deleted timestamp JSON: ${timestampJsonPath}`);
|
|
81166
|
+
} catch (error82) {
|
|
81167
|
+
console.error(`Error deleting timestamp JSON ${timestampJsonPath}:`, error82);
|
|
81168
|
+
}
|
|
80964
81169
|
}
|
|
80965
81170
|
async function cleanupConfig(configState) {
|
|
80966
|
-
if (
|
|
80967
|
-
|
|
81171
|
+
if (configState.configPath) {
|
|
81172
|
+
try {
|
|
81173
|
+
if (configState.wasCreated) {
|
|
81174
|
+
await fs10.unlink(configState.configPath);
|
|
81175
|
+
console.log(
|
|
81176
|
+
`Cleaned up created config file: ${configState.configPath}`
|
|
81177
|
+
);
|
|
81178
|
+
} else if (configState.wasModified && configState.originalContent) {
|
|
81179
|
+
await fs10.writeFile(configState.configPath, configState.originalContent);
|
|
81180
|
+
console.log(`Restored original config: ${configState.configPath}`);
|
|
81181
|
+
}
|
|
81182
|
+
} catch (error82) {
|
|
81183
|
+
console.error("Error cleaning up config:", error82);
|
|
81184
|
+
}
|
|
80968
81185
|
}
|
|
80969
|
-
|
|
80970
|
-
|
|
80971
|
-
await fs10.unlink(configState.
|
|
80972
|
-
console.log(`Cleaned up
|
|
80973
|
-
}
|
|
80974
|
-
|
|
80975
|
-
console.log(`Restored original config: ${configState.configPath}`);
|
|
81186
|
+
if (configState.reporterPath && configState.reporterWasCreated) {
|
|
81187
|
+
try {
|
|
81188
|
+
await fs10.unlink(configState.reporterPath);
|
|
81189
|
+
console.log(`Cleaned up reporter file: ${configState.reporterPath}`);
|
|
81190
|
+
} catch (error82) {
|
|
81191
|
+
console.error("Error cleaning up reporter:", error82);
|
|
80976
81192
|
}
|
|
80977
|
-
} catch (error82) {
|
|
80978
|
-
console.error("Error cleaning up config:", error82);
|
|
80979
81193
|
}
|
|
80980
81194
|
}
|
|
80981
81195
|
async function runPlaywrightTestWithVideo(options) {
|
|
@@ -80988,12 +81202,13 @@ async function runPlaywrightTestWithVideo(options) {
|
|
|
80988
81202
|
await ensureTestResultsInGitignore(repoLocation);
|
|
80989
81203
|
const testResult = await runPlaywrightTest(repoLocation, testFilePath);
|
|
80990
81204
|
const videoPath = await findVideoFile(repoLocation);
|
|
81205
|
+
const timestampJsonPath = await findTimestampJsonFile(repoLocation);
|
|
80991
81206
|
let uploadStatus;
|
|
80992
81207
|
if (responseUrl) {
|
|
80993
|
-
uploadStatus = await uploadVideo(videoPath, responseUrl);
|
|
80994
|
-
await
|
|
81208
|
+
uploadStatus = await uploadVideo(videoPath, timestampJsonPath, responseUrl);
|
|
81209
|
+
await deleteTestFiles(videoPath, timestampJsonPath);
|
|
80995
81210
|
} else {
|
|
80996
|
-
console.log("No responseUrl provided, keeping
|
|
81211
|
+
console.log("No responseUrl provided, keeping files locally");
|
|
80997
81212
|
}
|
|
80998
81213
|
await cleanupConfig(configState);
|
|
80999
81214
|
return {
|
package/dist/staklink-cli.cjs
CHANGED
|
@@ -10905,7 +10905,7 @@ var glob = Object.assign(glob_, {
|
|
|
10905
10905
|
glob.glob = glob;
|
|
10906
10906
|
|
|
10907
10907
|
// src/proxy/version.ts
|
|
10908
|
-
var VERSION = "0.3.
|
|
10908
|
+
var VERSION = "0.3.26";
|
|
10909
10909
|
|
|
10910
10910
|
// src/cli.ts
|
|
10911
10911
|
var STAKLINK_PROXY = "staklink-proxy";
|
package/package.json
CHANGED
|
Binary file
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
{
|
|
2
|
+
"testTitle": "YOLO page should display YOLO text",
|
|
3
|
+
"testId": "ea70bc1c4bc8cb3ef066-ef50a3f3fbda7cffd2c6",
|
|
4
|
+
"status": "passed",
|
|
5
|
+
"duration": 2661,
|
|
6
|
+
"startTime": "2025-11-20T05:03:47.154Z",
|
|
7
|
+
"videoPath": "/Users/evanfeenstra/code/sphinx2/staklink/test-results/scripts-demo-test-YOLO-page-should-display-YOLO-text/video.webm",
|
|
8
|
+
"actions": [
|
|
9
|
+
{
|
|
10
|
+
"title": "Navigate to \"/\"",
|
|
11
|
+
"category": "pw:api",
|
|
12
|
+
"timestamp": "2025-11-20T05:03:47.791Z",
|
|
13
|
+
"relativeMs": 637,
|
|
14
|
+
"duration": 505,
|
|
15
|
+
"stepPath": [
|
|
16
|
+
"Navigate to \"/\""
|
|
17
|
+
],
|
|
18
|
+
"location": {
|
|
19
|
+
"file": "/Users/evanfeenstra/code/sphinx2/staklink/scripts/demo-test.spec.ts",
|
|
20
|
+
"line": 5,
|
|
21
|
+
"column": 14
|
|
22
|
+
},
|
|
23
|
+
"sourceCode": "await page.goto('http://localhost:8080', { waitUntil: 'networkidle' });"
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
"title": "Wait for load state \"domcontentloaded\"",
|
|
27
|
+
"category": "pw:api",
|
|
28
|
+
"timestamp": "2025-11-20T05:03:47.793Z",
|
|
29
|
+
"relativeMs": 639,
|
|
30
|
+
"duration": 1,
|
|
31
|
+
"stepPath": [
|
|
32
|
+
"Wait for load state \"domcontentloaded\""
|
|
33
|
+
],
|
|
34
|
+
"location": {
|
|
35
|
+
"file": "/Users/evanfeenstra/code/sphinx2/staklink/scripts/demo-test.spec.ts",
|
|
36
|
+
"line": 8,
|
|
37
|
+
"column": 14
|
|
38
|
+
},
|
|
39
|
+
"sourceCode": "await page.waitForLoadState('domcontentloaded');"
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
"title": "Expect \"toHaveText\"",
|
|
43
|
+
"category": "expect",
|
|
44
|
+
"timestamp": "2025-11-20T05:03:47.815Z",
|
|
45
|
+
"relativeMs": 661,
|
|
46
|
+
"duration": 21,
|
|
47
|
+
"stepPath": [
|
|
48
|
+
"Expect \"toHaveText\""
|
|
49
|
+
],
|
|
50
|
+
"location": {
|
|
51
|
+
"file": "/Users/evanfeenstra/code/sphinx2/staklink/scripts/demo-test.spec.ts",
|
|
52
|
+
"line": 11,
|
|
53
|
+
"column": 36
|
|
54
|
+
},
|
|
55
|
+
"sourceCode": "await expect(page.locator('h1')).toHaveText('YOLO');"
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
"title": "Expect \"toBeVisible\"",
|
|
59
|
+
"category": "expect",
|
|
60
|
+
"timestamp": "2025-11-20T05:03:47.817Z",
|
|
61
|
+
"relativeMs": 663,
|
|
62
|
+
"duration": 2,
|
|
63
|
+
"stepPath": [
|
|
64
|
+
"Expect \"toBeVisible\""
|
|
65
|
+
],
|
|
66
|
+
"location": {
|
|
67
|
+
"file": "/Users/evanfeenstra/code/sphinx2/staklink/scripts/demo-test.spec.ts",
|
|
68
|
+
"line": 14,
|
|
69
|
+
"column": 40
|
|
70
|
+
},
|
|
71
|
+
"sourceCode": "await expect(page.locator('button')).toBeVisible();"
|
|
72
|
+
},
|
|
73
|
+
{
|
|
74
|
+
"title": "Expect \"toHaveText\"",
|
|
75
|
+
"category": "expect",
|
|
76
|
+
"timestamp": "2025-11-20T05:03:47.819Z",
|
|
77
|
+
"relativeMs": 665,
|
|
78
|
+
"duration": 2,
|
|
79
|
+
"stepPath": [
|
|
80
|
+
"Expect \"toHaveText\""
|
|
81
|
+
],
|
|
82
|
+
"location": {
|
|
83
|
+
"file": "/Users/evanfeenstra/code/sphinx2/staklink/scripts/demo-test.spec.ts",
|
|
84
|
+
"line": 15,
|
|
85
|
+
"column": 40
|
|
86
|
+
},
|
|
87
|
+
"sourceCode": "await expect(page.locator('button')).toHaveText('Test');"
|
|
88
|
+
},
|
|
89
|
+
{
|
|
90
|
+
"title": "Wait for timeout",
|
|
91
|
+
"category": "pw:api",
|
|
92
|
+
"timestamp": "2025-11-20T05:03:49.821Z",
|
|
93
|
+
"relativeMs": 2667,
|
|
94
|
+
"duration": 2002,
|
|
95
|
+
"stepPath": [
|
|
96
|
+
"Wait for timeout"
|
|
97
|
+
],
|
|
98
|
+
"location": {
|
|
99
|
+
"file": "/Users/evanfeenstra/code/sphinx2/staklink/scripts/demo-test.spec.ts",
|
|
100
|
+
"line": 18,
|
|
101
|
+
"column": 14
|
|
102
|
+
},
|
|
103
|
+
"sourceCode": "await page.waitForTimeout(2000);"
|
|
104
|
+
}
|
|
105
|
+
]
|
|
106
|
+
}
|