@probolabs/playwright 1.4.0-rc.3 โ†’ 1.4.0-rc.5

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/index.d.ts CHANGED
@@ -433,6 +433,11 @@ declare class ProboCodeGenerator {
433
433
  * Get default viewport dimensions
434
434
  */
435
435
  private static getDefaultViewPort;
436
+ /**
437
+ * Validate and normalize viewport dimensions
438
+ * Returns a valid viewport object with numeric width and height, falling back to defaults if invalid
439
+ */
440
+ private static normalizeViewPort;
436
441
  /**
437
442
  * Generate code for a single scenario
438
443
  * Fetches scenario data, converts to Interaction[], generates code
@@ -470,6 +475,7 @@ interface TestStatistics {
470
475
  interface TestSuiteRunOptions {
471
476
  outputDir?: string;
472
477
  includeReporter?: boolean;
478
+ playwrightArgs?: string[];
473
479
  onStatusUpdate?: (updates: Partial<{
474
480
  status: string;
475
481
  exit_code: number;
package/dist/index.js CHANGED
@@ -1656,7 +1656,6 @@ export default defineConfig({
1656
1656
  // Keep Playwright's default console output, plus HTML report${includeReporter ? ', plus Probo live progress reporter' : ''}.
1657
1657
  reporter: ${JSON.stringify(reporters)},
1658
1658
  use: {
1659
- headless: true,
1660
1659
  ignoreHTTPSErrors: true,
1661
1660
  actionTimeout: 30000,
1662
1661
  navigationTimeout: 30000,
@@ -1665,7 +1664,6 @@ export default defineConfig({
1665
1664
  trace: 'on',
1666
1665
  },
1667
1666
  retries: 0,
1668
- workers: 1,
1669
1667
  });
1670
1668
  `;
1671
1669
  }
@@ -5850,6 +5848,19 @@ class ProboCodeGenerator {
5850
5848
  static getDefaultViewPort() {
5851
5849
  return { width: 1280, height: 720 };
5852
5850
  }
5851
+ /**
5852
+ * Validate and normalize viewport dimensions
5853
+ * Returns a valid viewport object with numeric width and height, falling back to defaults if invalid
5854
+ */
5855
+ static normalizeViewPort(viewPort) {
5856
+ const defaultViewPort = this.getDefaultViewPort();
5857
+ if (!viewPort) {
5858
+ return defaultViewPort;
5859
+ }
5860
+ const width = typeof viewPort.width === 'number' && !isNaN(viewPort.width) ? viewPort.width : defaultViewPort.width;
5861
+ const height = typeof viewPort.height === 'number' && !isNaN(viewPort.height) ? viewPort.height : defaultViewPort.height;
5862
+ return { width, height };
5863
+ }
5853
5864
  /**
5854
5865
  * Generate code for a single scenario
5855
5866
  * Fetches scenario data, converts to Interaction[], generates code
@@ -5868,7 +5879,7 @@ class ProboCodeGenerator {
5868
5879
  const interactions = this.convertBackendInteractionsToInteractionFormat(scenarioData.interactions || []);
5869
5880
  // Get settings and viewport
5870
5881
  const settings = (options === null || options === void 0 ? void 0 : options.recorderSettings) || this.getDefaultRecorderSettings();
5871
- const viewPort = (options === null || options === void 0 ? void 0 : options.viewPort) || scenarioData.viewPort || this.getDefaultViewPort();
5882
+ const viewPort = this.normalizeViewPort((options === null || options === void 0 ? void 0 : options.viewPort) || scenarioData.viewPort);
5872
5883
  // Get parameter table rows
5873
5884
  const rows = scenarioData.parameterTable || [];
5874
5885
  // Generate code
@@ -6054,6 +6065,22 @@ class TestSuiteRunner {
6054
6065
  throw new Error(`Failed to lookup test suite: ${response.status} ${errorText}`);
6055
6066
  }
6056
6067
  const data = await response.json();
6068
+ // TEMPORARY DEBUG: Output the full response
6069
+ console.log('๐Ÿ” DEBUG: API Response URL:', url);
6070
+ console.log('๐Ÿ” DEBUG: API Response Status:', response.status);
6071
+ console.log('๐Ÿ” DEBUG: API Response Data:', JSON.stringify(data, null, 2));
6072
+ console.log('๐Ÿ” DEBUG: Is Array?', Array.isArray(data));
6073
+ console.log('๐Ÿ” DEBUG: Array length:', Array.isArray(data) ? data.length : 'N/A');
6074
+ console.log('๐Ÿ” DEBUG: Has results?', !!data.results);
6075
+ console.log('๐Ÿ” DEBUG: Results is Array?', Array.isArray(data.results));
6076
+ console.log('๐Ÿ” DEBUG: Results length:', Array.isArray(data.results) ? data.results.length : 'N/A');
6077
+ if (Array.isArray(data) && data.length > 0) {
6078
+ console.log('๐Ÿ” DEBUG: First item:', JSON.stringify(data[0], null, 2));
6079
+ }
6080
+ if (data.results && Array.isArray(data.results) && data.results.length > 0) {
6081
+ console.log('๐Ÿ” DEBUG: First result:', JSON.stringify(data.results[0], null, 2));
6082
+ }
6083
+ console.log('');
6057
6084
  if (Array.isArray(data) && data.length > 0) {
6058
6085
  return data[0].id;
6059
6086
  }
@@ -6072,7 +6099,52 @@ class TestSuiteRunner {
6072
6099
  if (codeGenResult.scenarios.length === 0) {
6073
6100
  throw new Error(`No scenarios found in test suite ${testSuiteId}. Cannot generate test files.`);
6074
6101
  }
6075
- // Ensure directories exist
6102
+ // Delete everything in the test suite directory except node_modules
6103
+ // This ensures a clean state while preserving dependencies for faster subsequent runs
6104
+ if (fs.existsSync(testSuiteDir)) {
6105
+ try {
6106
+ const nodeModulesPath = path.join(testSuiteDir, 'node_modules');
6107
+ const hasNodeModules = fs.existsSync(nodeModulesPath);
6108
+ // Temporarily move node_modules out of the way if it exists
6109
+ let tempNodeModulesPath = null;
6110
+ if (hasNodeModules) {
6111
+ tempNodeModulesPath = path.join(testSuiteDir, '..', `node_modules.temp.${testSuiteId}`);
6112
+ // Remove temp directory if it exists from a previous failed run
6113
+ if (fs.existsSync(tempNodeModulesPath)) {
6114
+ fs.rmSync(tempNodeModulesPath, { recursive: true, force: true });
6115
+ }
6116
+ fs.renameSync(nodeModulesPath, tempNodeModulesPath);
6117
+ console.log(`๐Ÿ“ฆ Preserved node_modules temporarily`);
6118
+ }
6119
+ // Delete everything in the directory
6120
+ const entries = fs.readdirSync(testSuiteDir, { withFileTypes: true });
6121
+ for (const entry of entries) {
6122
+ const entryPath = path.join(testSuiteDir, entry.name);
6123
+ try {
6124
+ if (entry.isDirectory()) {
6125
+ fs.rmSync(entryPath, { recursive: true, force: true });
6126
+ }
6127
+ else {
6128
+ fs.unlinkSync(entryPath);
6129
+ }
6130
+ }
6131
+ catch (error) {
6132
+ console.warn(`โš ๏ธ Failed to delete ${entry.name}:`, error);
6133
+ }
6134
+ }
6135
+ console.log(`๐Ÿ—‘๏ธ Cleaned test suite directory (preserved node_modules)`);
6136
+ // Move node_modules back
6137
+ if (hasNodeModules && tempNodeModulesPath) {
6138
+ fs.renameSync(tempNodeModulesPath, nodeModulesPath);
6139
+ console.log(`๐Ÿ“ฆ Restored node_modules`);
6140
+ }
6141
+ }
6142
+ catch (error) {
6143
+ console.warn(`โš ๏ธ Failed to clean test suite directory ${testSuiteDir}:`, error);
6144
+ // Continue anyway - we'll overwrite files as needed
6145
+ }
6146
+ }
6147
+ // Ensure directories exist (will recreate after deletion)
6076
6148
  ensureDirectoryExists(testSuiteDir);
6077
6149
  const testsDir = path.join(testSuiteDir, 'tests');
6078
6150
  ensureDirectoryExists(testsDir);
@@ -6159,7 +6231,7 @@ class TestSuiteRunner {
6159
6231
  * Generates files, installs dependencies, and executes tests
6160
6232
  */
6161
6233
  static async runTestSuite(testSuiteId, apiToken, apiUrl, testSuiteName, runId, options = {}) {
6162
- const { outputDir, includeReporter = true, onStatusUpdate, onStdout, onStderr, onReporterEvent, } = options;
6234
+ const { outputDir, includeReporter = true, playwrightArgs = [], onStatusUpdate, onStdout, onStderr, onReporterEvent, } = options;
6163
6235
  const testSuiteDir = outputDir || getDefaultTestSuiteDir(testSuiteId, testSuiteName);
6164
6236
  let currentRunId = runId;
6165
6237
  try {
@@ -6238,6 +6310,9 @@ class TestSuiteRunner {
6238
6310
  }
6239
6311
  // Run Playwright tests with streaming output
6240
6312
  console.log(`๐Ÿš€ Running Playwright tests in ${testSuiteDir}...`);
6313
+ if (playwrightArgs.length > 0) {
6314
+ console.log(`๐Ÿงช Playwright extra args: ${playwrightArgs.join(' ')}`);
6315
+ }
6241
6316
  return new Promise(async (resolve) => {
6242
6317
  var _a, _b;
6243
6318
  let stdout = '';
@@ -6254,7 +6329,7 @@ class TestSuiteRunner {
6254
6329
  let lastStepsUpdate = 0;
6255
6330
  const collectedSteps = [];
6256
6331
  // Use spawn for streaming output
6257
- const testProcess = spawn('npx', ['playwright', 'test'], {
6332
+ const testProcess = spawn('npx', ['playwright', 'test', ...playwrightArgs], {
6258
6333
  cwd: testSuiteDir,
6259
6334
  shell: true,
6260
6335
  stdio: ['ignore', 'pipe', 'pipe'],