@dionlarson/playwright-orchestrator-pg 1.5.0 → 1.6.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.
@@ -24,40 +24,27 @@ export class PostgreSQLAdapter extends Adapter {
24
24
  this.testInfoHistoryTable = pg.escapeIdentifier(`${tableNamePrefix}_test_info_history`);
25
25
  }
26
26
  async getNextTest(runId, config) {
27
- const client = await this.pool.connect();
28
- try {
29
- console.log(`[pg-adapter] getNextTest: BEGIN transaction`);
30
- await client.query('BEGIN');
31
- const result = await client.query({
32
- text: `WITH next_test AS (
27
+ // Use UPDATE with subquery and double-check status in outer WHERE.
28
+ // The subquery's FOR UPDATE SKIP LOCKED finds a Ready row, but the lock
29
+ // is released when the subquery returns. Adding status=$2 in the outer
30
+ // WHERE ensures only one transaction succeeds if multiple grab the same order_num.
31
+ const result = await this.pool.query({
32
+ text: `UPDATE ${this.testsTable}
33
+ SET status = $3, updated = NOW()
34
+ WHERE run_id = $1 AND status = $2 AND order_num = (
33
35
  SELECT order_num FROM ${this.testsTable}
34
36
  WHERE run_id = $1 AND status = $2
35
37
  ORDER BY order_num
36
38
  LIMIT 1
37
39
  FOR UPDATE SKIP LOCKED
38
40
  )
39
- UPDATE ${this.testsTable} t
40
- SET status = $3, updated = NOW()
41
- FROM next_test
42
- WHERE t.run_id = $1 AND t.order_num = next_test.order_num
43
41
  RETURNING *`,
44
- values: [runId, TestStatus.Ready, TestStatus.Ongoing],
45
- });
46
- console.log(`[pg-adapter] getNextTest: got ${result.rowCount} rows, order_num=${result.rows[0]?.order_num}`);
47
- await client.query('COMMIT');
48
- console.log(`[pg-adapter] getNextTest: COMMIT`);
49
- if (result.rowCount === 0)
50
- return undefined;
51
- const { file, line, character, project, timeout, order_num } = result.rows[0];
52
- return { file, position: `${line}:${character}`, project, timeout, order: order_num };
53
- }
54
- catch (e) {
55
- console.log(`[pg-adapter] getNextTest: ERROR ${e}, rolling back`);
56
- await client.query('ROLLBACK');
57
- }
58
- finally {
59
- client.release();
60
- }
42
+ values: [runId, TestStatus.Ready, TestStatus.Ongoing],
43
+ });
44
+ if (result.rowCount === 0)
45
+ return undefined;
46
+ const { file, line, character, project, timeout, order_num, title } = result.rows[0];
47
+ return { file, position: `${line}:${character}`, project, timeout, order: order_num, title };
61
48
  }
62
49
  async finishTest(params) {
63
50
  await this.updateTestWithResults(TestStatus.Passed, params);
@@ -73,7 +60,7 @@ export class PostgreSQLAdapter extends Adapter {
73
60
  text: `INSERT INTO ${this.configTable} (id, status, config) VALUES ($1, $2, $3)`,
74
61
  values: [runId, RunStatus.Created, JSON.stringify({ ...testRun.config, args, historyWindow })],
75
62
  });
76
- const fields = ['order_num', 'file', 'line', 'character', 'project', 'timeout'];
63
+ const fields = ['order_num', 'file', 'line', 'character', 'project', 'timeout', 'title'];
77
64
  await this.pool.query({
78
65
  text: `INSERT INTO ${this.testsTable} (run_id, ${fields.join(', ')}) VALUES ${tests
79
66
  .map((_, i) => {
@@ -84,9 +71,9 @@ export class PostgreSQLAdapter extends Adapter {
84
71
  .join(', ')}`,
85
72
  values: [
86
73
  runId,
87
- ...tests.flatMap(({ position, order, file, project, timeout }) => {
74
+ ...tests.flatMap(({ position, order, file, project, timeout, title }) => {
88
75
  const [line, character] = position.split(':');
89
- return [order, file, line, character, project, timeout];
76
+ return [order, file, line, character, project, timeout, title];
90
77
  }),
91
78
  ],
92
79
  });
@@ -107,12 +94,14 @@ export class PostgreSQLAdapter extends Adapter {
107
94
  character INT NOT NULL,
108
95
  project TEXT NOT NULL,
109
96
  timeout INT NOT NULL,
97
+ title TEXT NOT NULL DEFAULT '',
110
98
  updated TIMESTAMP NOT NULL DEFAULT NOW(),
111
99
  report JSONB,
112
100
  PRIMARY KEY (run_id, order_num),
113
101
  FOREIGN KEY (run_id) REFERENCES ${this.configTable}(id)
114
102
  );
115
103
  CREATE INDEX IF NOT EXISTS status_idx ON ${this.testsTable}(status);
104
+ ALTER TABLE ${this.testsTable} ADD COLUMN IF NOT EXISTS title TEXT NOT NULL DEFAULT '';
116
105
  CREATE TABLE IF NOT EXISTS ${this.testInfoTable} (
117
106
  id SERIAL PRIMARY KEY,
118
107
  name TEXT NOT NULL,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dionlarson/playwright-orchestrator-pg",
3
- "version": "1.5.0",
3
+ "version": "1.6.0",
4
4
  "keywords": [],
5
5
  "author": "Rostyslav Kudrevatykh",
6
6
  "license": "Apache-2.0",