Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@
"bin": "./build/src/index.js",
"main": "index.js",
"scripts": {
"build": "tsc && node --experimental-strip-types --no-warnings=ExperimentalWarning scripts/post-build.ts",
"clean": "rm -rf build",
"build": "npm run clean && tsc && node --experimental-strip-types --no-warnings=ExperimentalWarning scripts/post-build.ts",
"typecheck": "tsc --noEmit",
"format": "eslint --cache --fix . && prettier --write --cache .",
"check-format": "eslint --cache . && prettier --check --cache .;",
Expand All @@ -19,6 +20,7 @@
"test:only": "npm run build && node --require ./build/tests/setup.js --no-warnings=ExperimentalWarning --test-reporter spec --test-force-exit --test --test-only \"build/tests/**/*.test.js\"",
"test:only:no-build": "node --require ./build/tests/setup.js --no-warnings=ExperimentalWarning --test-reporter spec --test-force-exit --test --test-only \"build/tests/**/*.test.js\"",
"test:update-snapshots": "npm run build && node --require ./build/tests/setup.js --no-warnings=ExperimentalWarning --test-force-exit --test --test-update-snapshots \"build/tests/**/*.test.js\"",
"test:coverage": "npm run build && node --require ./build/tests/setup.js --no-warnings=ExperimentalWarning --experimental-test-coverage --test-reporter spec --test-force-exit --test \"build/tests/**/*.test.js\"",
"prepare": "node --experimental-strip-types scripts/prepare.ts",
"sync-server-json-version": "node --experimental-strip-types scripts/sync-server-json-version.ts && npm run format"
},
Expand Down
77 changes: 77 additions & 0 deletions tests/Mutex.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
import {describe, it} from 'node:test';
import {Mutex} from '../src/Mutex.js';
import assert from 'node:assert';

describe('Mutex', () => {
it('should acquire and release the lock', async () => {
const mutex = new Mutex();
const guard = await mutex.acquire();
guard.dispose();
});

it('should ensure only one user can acquire the lock at a time', async () => {
const mutex = new Mutex();
await mutex.acquire();

let acquired = false;
mutex.acquire().then(() => {
acquired = true;
});

// Give the promise a chance to resolve if it's not waiting for the lock.
await new Promise(resolve => setTimeout(resolve, 0));

assert.strictEqual(acquired, false, 'Mutex should not have been acquired');
});

it('should allow acquiring the lock again after it has been released', async () => {
const mutex = new Mutex();
const guard1 = await mutex.acquire();
guard1.dispose();

const guard2 = await mutex.acquire();
guard2.dispose();
});

it('should handle multiple concurrent requests in FIFO order', async () => {
const mutex = new Mutex();
const order: number[] = [];

const p1 = mutex.acquire().then(guard => {
order.push(1);
guard.dispose();
});

const p2 = mutex.acquire().then(guard => {
order.push(2);
guard.dispose();
});

const p3 = mutex.acquire().then(guard => {
order.push(3);
guard.dispose();
});

await Promise.all([p1, p2, p3]);

assert.deepStrictEqual(order, [1, 2, 3], 'The mutex should have been acquired in FIFO order');
});

it('should work with async/await', async () => {
const mutex = new Mutex();
const guard = await mutex.acquire();

let acquired = false;
mutex.acquire().then(() => {
acquired = true;
});

await new Promise(resolve => setTimeout(resolve, 0));
assert.strictEqual(acquired, false, 'Mutex should not have been acquired');

guard.dispose();

await new Promise(resolve => setTimeout(resolve, 0));
assert.strictEqual(acquired, true, 'Mutex should have been acquired');
});
});
6 changes: 5 additions & 1 deletion tests/tools/screenshot.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,8 +77,12 @@ describe('screenshot', () => {
it('with full page resulting in a large screenshot', async () => {
await withBrowser(async (response, context) => {
const page = context.getSelectedPage();
// This is a large page that will result in a screenshot that is >2MB.
// The original size of 7,000 was too large for Puppeteer to handle,
// causing a protocol error. This size is large enough to trigger the
// file-saving logic without causing an error.
await page.setContent(
`<div style="color:blue;">test</div>`.repeat(7_000),
`<div style="color:blue;">test</div>`.repeat(4_000),
);
await screenshot.handler(
{params: {format: 'png', fullPage: true}},
Expand Down