@zohodesk/testinglibrary 3.1.0 → 3.1.2
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/build/core/playwright/builtInFixtures/executionContext.js +17 -0
- package/build/core/playwright/builtInFixtures/index.js +3 -1
- package/build/core/playwright/builtInFixtures/page.js +4 -2
- package/build/core/playwright/helpers/auth/checkAuthCookies.js +8 -9
- package/build/core/playwright/helpers/auth/loginSteps.js +12 -3
- package/build/core/playwright/helpers/fileMutex.js +21 -26
- package/build/core/playwright/tagProcessor.js +18 -28
- package/build/test/core/playwright/buildInFixtures/__tests__/executionContext.test.js +27 -0
- package/build/test/core/playwright/helpers/__tests__/fileMutex.test.js +2 -19
- package/npm-shrinkwrap.json +3345 -1546
- package/package.json +1 -1
- package/unit_reports/unit-report.html +260 -0
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.default = void 0;
|
|
7
|
+
var _page = require("./page");
|
|
8
|
+
var _default = exports.default = {
|
|
9
|
+
executionContext: async ({
|
|
10
|
+
$tags
|
|
11
|
+
}, use) => {
|
|
12
|
+
let testPortalActorDetails = {
|
|
13
|
+
actorInfo: (0, _page.getCustomAccountDetails)($tags)
|
|
14
|
+
};
|
|
15
|
+
await use(testPortalActorDetails);
|
|
16
|
+
}
|
|
17
|
+
};
|
|
@@ -11,6 +11,7 @@ var _cacheLayer = _interopRequireDefault(require("./cacheLayer"));
|
|
|
11
11
|
var _addTags = _interopRequireDefault(require("./addTags"));
|
|
12
12
|
var _i18N = _interopRequireDefault(require("./i18N"));
|
|
13
13
|
var _unauthenticatedPage = _interopRequireDefault(require("./unauthenticatedPage"));
|
|
14
|
+
var _executionContext = _interopRequireDefault(require("./executionContext"));
|
|
14
15
|
function extractTagsFromTitle(text) {
|
|
15
16
|
return text.match(/@\w+/g) || [];
|
|
16
17
|
}
|
|
@@ -20,7 +21,8 @@ function getBuiltInFixtures(bddMode) {
|
|
|
20
21
|
..._context.default,
|
|
21
22
|
..._cacheLayer.default,
|
|
22
23
|
..._i18N.default,
|
|
23
|
-
..._unauthenticatedPage.default
|
|
24
|
+
..._unauthenticatedPage.default,
|
|
25
|
+
..._executionContext.default
|
|
24
26
|
};
|
|
25
27
|
if (bddMode) {
|
|
26
28
|
builtInFixtures = {
|
|
@@ -4,6 +4,7 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
exports.default = void 0;
|
|
7
|
+
exports.getCustomAccountDetails = getCustomAccountDetails;
|
|
7
8
|
var _auth = require("../helpers/auth");
|
|
8
9
|
var _readConfigFile = require("../readConfigFile");
|
|
9
10
|
/* eslint-disable global-require */
|
|
@@ -57,9 +58,10 @@ var _default = exports.default = {
|
|
|
57
58
|
page: async ({
|
|
58
59
|
context,
|
|
59
60
|
$tags,
|
|
60
|
-
page
|
|
61
|
+
page,
|
|
62
|
+
executionContext
|
|
61
63
|
}, use, testInfo) => {
|
|
62
|
-
let testPortalDetails =
|
|
64
|
+
let testPortalDetails = executionContext.actorInfo;
|
|
63
65
|
let testDetails = {
|
|
64
66
|
page,
|
|
65
67
|
$tags,
|
|
@@ -24,11 +24,7 @@ function getAuthFileDirectory() {
|
|
|
24
24
|
return _path.default.resolve(_path.default.join(uatDirectory, 'playwright', '.auth'));
|
|
25
25
|
}
|
|
26
26
|
function verifyIfCookieFileExists(authFile) {
|
|
27
|
-
(0,
|
|
28
|
-
if (!(0, _fs.existsSync)(authFile)) {
|
|
29
|
-
console.log('creating auth file..');
|
|
30
|
-
(0, _fs.writeFileSync)(authFile, JSON.stringify(authContent, null, 2));
|
|
31
|
-
}
|
|
27
|
+
return (0, _fs.existsSync)(authFile);
|
|
32
28
|
}
|
|
33
29
|
function convertCookiesToParse(cookies, authFilePath) {
|
|
34
30
|
try {
|
|
@@ -39,8 +35,11 @@ function convertCookiesToParse(cookies, authFilePath) {
|
|
|
39
35
|
}
|
|
40
36
|
}
|
|
41
37
|
async function loadCookiesIfPresent(page, authFile) {
|
|
42
|
-
verifyIfCookieFileExists(authFile)
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
38
|
+
if (verifyIfCookieFileExists(authFile)) {
|
|
39
|
+
const fileContent = (0, _fs.readFileSync)(authFile);
|
|
40
|
+
const stroageState = convertCookiesToParse(fileContent, authFile);
|
|
41
|
+
if (stroageState.cookies) {
|
|
42
|
+
await page.context().addCookies(stroageState.cookies);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
46
45
|
}
|
|
@@ -10,6 +10,7 @@ var _fileMutex = _interopRequireDefault(require("../fileMutex"));
|
|
|
10
10
|
var _fileMutexConfig = require("../../constants/fileMutexConfig");
|
|
11
11
|
var _checkAuthCookies = require("./checkAuthCookies");
|
|
12
12
|
var _checkAuthDirectory = require("../checkAuthDirectory");
|
|
13
|
+
var _fs = require("fs");
|
|
13
14
|
/* eslint-disable no-console */
|
|
14
15
|
|
|
15
16
|
async function performLoginSteps(testInfo, isLoggedIn, loginSteps) {
|
|
@@ -21,9 +22,15 @@ async function performLoginSteps(testInfo, isLoggedIn, loginSteps) {
|
|
|
21
22
|
authFilePrefix = authFilePrefix || email;
|
|
22
23
|
const authFile = _path.default.resolve(_path.default.join((0, _checkAuthCookies.getAuthFileDirectory)(), `${authFilePrefix}-cookies.json`));
|
|
23
24
|
const lockFileName = email.replace(/[@.]/g, '_');
|
|
24
|
-
const fileMutex = new _fileMutex.default((0, _checkAuthDirectory.getLockDirectoryPath)(), lockFileName,
|
|
25
|
+
const fileMutex = new _fileMutex.default((0, _checkAuthDirectory.getLockDirectoryPath)(), lockFileName, _fileMutexConfig.fileDeletionTimeoutConfig);
|
|
26
|
+
let loginUsingCookie = false;
|
|
25
27
|
try {
|
|
26
|
-
|
|
28
|
+
if ((0, _checkAuthCookies.verifyIfCookieFileExists)(authFile)) {
|
|
29
|
+
console.log(`${email} Cookie file exists. Loading cookies, worker index - ${process.env.TEST_WORKER_INDEX}`);
|
|
30
|
+
loginUsingCookie = true;
|
|
31
|
+
} else {
|
|
32
|
+
await fileMutex.acquire();
|
|
33
|
+
}
|
|
27
34
|
await (0, _checkAuthCookies.loadCookiesIfPresent)(page, authFile);
|
|
28
35
|
const isAlreadyLoggedIn = await isLoggedIn(testInfo);
|
|
29
36
|
if (!isAlreadyLoggedIn) {
|
|
@@ -36,7 +43,9 @@ async function performLoginSteps(testInfo, isLoggedIn, loginSteps) {
|
|
|
36
43
|
} catch (error) {
|
|
37
44
|
console.error(`Error during login for ${email}:`, error);
|
|
38
45
|
} finally {
|
|
39
|
-
|
|
46
|
+
if (!loginUsingCookie) {
|
|
47
|
+
await fileMutex.release();
|
|
48
|
+
}
|
|
40
49
|
}
|
|
41
50
|
}
|
|
42
51
|
var _default = exports.default = performLoginSteps;
|
|
@@ -7,30 +7,24 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
7
7
|
exports.default = void 0;
|
|
8
8
|
var _path = _interopRequireDefault(require("path"));
|
|
9
9
|
var _fs = require("fs");
|
|
10
|
-
function _classPrivateMethodInitSpec(
|
|
11
|
-
function _checkPrivateRedeclaration(
|
|
12
|
-
function
|
|
13
|
-
var
|
|
10
|
+
function _classPrivateMethodInitSpec(e, a) { _checkPrivateRedeclaration(e, a), a.add(e); }
|
|
11
|
+
function _checkPrivateRedeclaration(e, t) { if (t.has(e)) throw new TypeError("Cannot initialize the same private elements twice on an object"); }
|
|
12
|
+
function _assertClassBrand(e, t, n) { if ("function" == typeof e ? e === t : e.has(t)) return arguments.length < 3 ? t : n; throw new TypeError("Private element is not present on this object"); }
|
|
13
|
+
var _FileMutex_brand = /*#__PURE__*/new WeakSet();
|
|
14
14
|
class FileMutex {
|
|
15
|
-
constructor(directory, lockFileName,
|
|
16
|
-
_classPrivateMethodInitSpec(this,
|
|
15
|
+
constructor(directory, lockFileName, fileDeletionTimeoutConfig) {
|
|
16
|
+
_classPrivateMethodInitSpec(this, _FileMutex_brand);
|
|
17
17
|
this.directory = directory;
|
|
18
18
|
this.lockFileName = lockFileName + ".lock";
|
|
19
|
-
this.email = email;
|
|
20
|
-
this.authFile = authFile;
|
|
21
19
|
this.fileDeletionTimeout = fileDeletionTimeoutConfig.timeout;
|
|
22
|
-
this.
|
|
23
|
-
|
|
20
|
+
this.lockFilePath = _assertClassBrand(_FileMutex_brand, this, _getLockFilePath).call(this);
|
|
21
|
+
_assertClassBrand(_FileMutex_brand, this, _createDirectoryIfNotExist).call(this);
|
|
24
22
|
}
|
|
25
23
|
async acquire() {
|
|
26
|
-
if ((0, _fs.existsSync)(this.authFile)) {
|
|
27
|
-
console.log(`${this.email} Cookie file exists. Loading cookies...`);
|
|
28
|
-
return;
|
|
29
|
-
}
|
|
30
24
|
return new Promise((resolve, reject) => {
|
|
31
25
|
if (!(0, _fs.existsSync)(this.lockFilePath)) {
|
|
32
26
|
(0, _fs.writeFileSync)(this.lockFilePath, 'locked');
|
|
33
|
-
console.log(`Lock file created: ${this.lockFilePath}`);
|
|
27
|
+
console.log(`Lock file created: ${this.lockFilePath}, worker index - ${process.env.TEST_WORKER_INDEX}`);
|
|
34
28
|
return resolve();
|
|
35
29
|
}
|
|
36
30
|
const timeout = setTimeout(() => {
|
|
@@ -41,7 +35,7 @@ class FileMutex {
|
|
|
41
35
|
try {
|
|
42
36
|
if (eventType === 'rename' && filename === this.lockFileName) {
|
|
43
37
|
clearTimeout(timeout);
|
|
44
|
-
console.log(`Lock file deleted! Proceeding
|
|
38
|
+
console.log(`Lock file deleted! Proceeding, worker index - ${process.env.TEST_WORKER_INDEX}`);
|
|
45
39
|
watcher.close();
|
|
46
40
|
resolve();
|
|
47
41
|
}
|
|
@@ -56,21 +50,22 @@ class FileMutex {
|
|
|
56
50
|
try {
|
|
57
51
|
if ((0, _fs.existsSync)(this.lockFilePath)) {
|
|
58
52
|
(0, _fs.unlinkSync)(this.lockFilePath);
|
|
59
|
-
console.log(`Lock file deleted: ${this.lockFilePath}`);
|
|
53
|
+
console.log(`Lock file deleted: ${this.lockFilePath}, worker index - ${process.env.TEST_WORKER_INDEX}`);
|
|
60
54
|
}
|
|
61
55
|
} catch (err) {
|
|
62
|
-
console.error(`Error deleting lock file: ${err.message}`);
|
|
63
|
-
|
|
64
|
-
}
|
|
65
|
-
async createDirectoryIfNotExist() {
|
|
66
|
-
if (!(0, _fs.existsSync)(this.directory)) {
|
|
67
|
-
(0, _fs.mkdirSync)(this.directory, {
|
|
68
|
-
recursive: true
|
|
69
|
-
});
|
|
56
|
+
console.error(`Error deleting lock file: ${err.message}, worker index - ${process.env.TEST_WORKER_INDEX}`);
|
|
57
|
+
throw err;
|
|
70
58
|
}
|
|
71
59
|
}
|
|
72
60
|
}
|
|
73
|
-
function
|
|
61
|
+
function _getLockFilePath() {
|
|
74
62
|
return _path.default.resolve(_path.default.join(this.directory, this.lockFileName));
|
|
75
63
|
}
|
|
64
|
+
async function _createDirectoryIfNotExist() {
|
|
65
|
+
if (!(0, _fs.existsSync)(this.directory)) {
|
|
66
|
+
(0, _fs.mkdirSync)(this.directory, {
|
|
67
|
+
recursive: true
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
}
|
|
76
71
|
var _default = exports.default = FileMutex;
|
|
@@ -1,23 +1,13 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
3
|
var _logger = require("../../utils/logger");
|
|
4
|
-
function _classPrivateMethodInitSpec(
|
|
5
|
-
function _checkPrivateRedeclaration(
|
|
6
|
-
function
|
|
7
|
-
var
|
|
8
|
-
var _parseEdition = /*#__PURE__*/new WeakSet();
|
|
9
|
-
var _processSingleEdition = /*#__PURE__*/new WeakSet();
|
|
10
|
-
var _processMultipleEditions = /*#__PURE__*/new WeakSet();
|
|
11
|
-
var _getEditionArgs = /*#__PURE__*/new WeakSet();
|
|
12
|
-
var _buildEditionTags = /*#__PURE__*/new WeakSet();
|
|
4
|
+
function _classPrivateMethodInitSpec(e, a) { _checkPrivateRedeclaration(e, a), a.add(e); }
|
|
5
|
+
function _checkPrivateRedeclaration(e, t) { if (t.has(e)) throw new TypeError("Cannot initialize the same private elements twice on an object"); }
|
|
6
|
+
function _assertClassBrand(e, t, n) { if ("function" == typeof e ? e === t : e.has(t)) return arguments.length < 3 ? t : n; throw new TypeError("Private element is not present on this object"); }
|
|
7
|
+
var _TagProcessor_brand = /*#__PURE__*/new WeakSet();
|
|
13
8
|
class TagProcessor {
|
|
14
9
|
constructor(editionOrder) {
|
|
15
|
-
_classPrivateMethodInitSpec(this,
|
|
16
|
-
_classPrivateMethodInitSpec(this, _getEditionArgs);
|
|
17
|
-
_classPrivateMethodInitSpec(this, _processMultipleEditions);
|
|
18
|
-
_classPrivateMethodInitSpec(this, _processSingleEdition);
|
|
19
|
-
_classPrivateMethodInitSpec(this, _parseEdition);
|
|
20
|
-
_classPrivateMethodInitSpec(this, _buildTagsString);
|
|
10
|
+
_classPrivateMethodInitSpec(this, _TagProcessor_brand);
|
|
21
11
|
this.editionOrder = editionOrder;
|
|
22
12
|
}
|
|
23
13
|
processTags(userArgs) {
|
|
@@ -25,36 +15,36 @@ class TagProcessor {
|
|
|
25
15
|
const edition = userArgs['edition'] || null;
|
|
26
16
|
if (!edition) return tagArgs;
|
|
27
17
|
const editionsArray = edition.split(',');
|
|
28
|
-
const editionTags = editionsArray.length === 1 ?
|
|
18
|
+
const editionTags = editionsArray.length === 1 ? _assertClassBrand(_TagProcessor_brand, this, _processSingleEdition).call(this, editionsArray[0], tagArgs) : _assertClassBrand(_TagProcessor_brand, this, _processMultipleEditions).call(this, editionsArray, tagArgs);
|
|
29
19
|
return editionTags;
|
|
30
20
|
}
|
|
31
21
|
}
|
|
32
|
-
function
|
|
22
|
+
function _buildTagsString(tags, editionTags) {
|
|
33
23
|
return tags && tags !== '' ? `${tags} and not (${editionTags})` : `not (${editionTags})`;
|
|
34
24
|
}
|
|
35
|
-
function
|
|
25
|
+
function _parseEdition(edition) {
|
|
36
26
|
if (edition.startsWith('<=')) return ['<=', edition.slice(2)];
|
|
37
27
|
if (edition.startsWith('>=')) return ['>=', edition.slice(2)];
|
|
38
28
|
if (edition.startsWith('<')) return ['<', edition.slice(1)];
|
|
39
29
|
if (edition.startsWith('>')) return ['>', edition.slice(1)];
|
|
40
30
|
return [null, edition];
|
|
41
31
|
}
|
|
42
|
-
function
|
|
43
|
-
const editionArgs =
|
|
32
|
+
function _processSingleEdition(selectedEdition, tagArgs) {
|
|
33
|
+
const editionArgs = _assertClassBrand(_TagProcessor_brand, this, _getEditionArgs).call(this, selectedEdition);
|
|
44
34
|
if (editionArgs && editionArgs.length > 0) {
|
|
45
|
-
const editionTags =
|
|
46
|
-
return
|
|
35
|
+
const editionTags = _assertClassBrand(_TagProcessor_brand, this, _buildEditionTags).call(this, editionArgs, 'or');
|
|
36
|
+
return _assertClassBrand(_TagProcessor_brand, this, _buildTagsString).call(this, tagArgs, editionTags);
|
|
47
37
|
}
|
|
48
38
|
_logger.Logger.log(_logger.Logger.INFO_TYPE, `No matching editions for ${selectedEdition} found. Running with default edition`);
|
|
49
39
|
return tagArgs;
|
|
50
40
|
}
|
|
51
|
-
function
|
|
41
|
+
function _processMultipleEditions(editionsArray, tagArgs) {
|
|
52
42
|
const filteredEditions = this.editionOrder.filter(edition => !editionsArray.includes(edition));
|
|
53
|
-
const editionTags =
|
|
54
|
-
return
|
|
43
|
+
const editionTags = _assertClassBrand(_TagProcessor_brand, this, _buildEditionTags).call(this, filteredEditions, 'or');
|
|
44
|
+
return _assertClassBrand(_TagProcessor_brand, this, _buildTagsString).call(this, tagArgs, editionTags);
|
|
55
45
|
}
|
|
56
|
-
function
|
|
57
|
-
const [operator, editionValue] =
|
|
46
|
+
function _getEditionArgs(selectedEdition) {
|
|
47
|
+
const [operator, editionValue] = _assertClassBrand(_TagProcessor_brand, this, _parseEdition).call(this, selectedEdition.toLowerCase());
|
|
58
48
|
const index = this.editionOrder.findIndex(edition => edition.toLowerCase() === editionValue);
|
|
59
49
|
if (index === -1) {
|
|
60
50
|
_logger.Logger.log(_logger.Logger.INFO_TYPE, `No matching editions for ${selectedEdition} found. Running with default edition`);
|
|
@@ -73,7 +63,7 @@ function _getEditionArgs2(selectedEdition) {
|
|
|
73
63
|
return this.editionOrder.filter((_, i) => i !== index);
|
|
74
64
|
}
|
|
75
65
|
}
|
|
76
|
-
function
|
|
66
|
+
function _buildEditionTags(editionArgs, operator = 'or') {
|
|
77
67
|
return editionArgs.map(edition => `@edition_${edition}`).join(` ${operator} `);
|
|
78
68
|
}
|
|
79
69
|
module.exports = TagProcessor;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
4
|
+
var _page = require("../../../../../core/playwright/builtInFixtures/page");
|
|
5
|
+
var _executionContext = _interopRequireDefault(require("../../../../../core/playwright/builtInFixtures/executionContext"));
|
|
6
|
+
jest.mock('../../../../../core/playwright/builtInFixtures/page');
|
|
7
|
+
describe('executionContext', () => {
|
|
8
|
+
test('should pass actorInfo with details from getCustomAccountDetails to use', async () => {
|
|
9
|
+
const mockTags = ['tag1', 'tag2'];
|
|
10
|
+
const mockActorInfo = {
|
|
11
|
+
id: '1',
|
|
12
|
+
edition: 'enterprise',
|
|
13
|
+
orgName: 'orgName',
|
|
14
|
+
profile: 'admin',
|
|
15
|
+
email: 'xxx.x+uat@zohotest.com'
|
|
16
|
+
};
|
|
17
|
+
_page.getCustomAccountDetails.mockReturnValue(mockActorInfo);
|
|
18
|
+
const use = jest.fn();
|
|
19
|
+
await _executionContext.default.executionContext({
|
|
20
|
+
$tags: mockTags
|
|
21
|
+
}, use);
|
|
22
|
+
expect(_page.getCustomAccountDetails).toHaveBeenCalledWith(mockTags);
|
|
23
|
+
expect(use).toHaveBeenCalledWith({
|
|
24
|
+
actorInfo: mockActorInfo
|
|
25
|
+
});
|
|
26
|
+
});
|
|
27
|
+
});
|
|
@@ -8,8 +8,6 @@ jest.mock('fs');
|
|
|
8
8
|
describe('FileMutex', () => {
|
|
9
9
|
const directory = '/tmp/locks';
|
|
10
10
|
const lockFileName = 'test-lock';
|
|
11
|
-
const email = 'test@example.com';
|
|
12
|
-
const authFile = '/tmp/authFile';
|
|
13
11
|
const fileDeletionTimeoutConfig = {
|
|
14
12
|
timeout: 1000
|
|
15
13
|
};
|
|
@@ -17,27 +15,14 @@ describe('FileMutex', () => {
|
|
|
17
15
|
let fileMutex;
|
|
18
16
|
beforeEach(() => {
|
|
19
17
|
jest.clearAllMocks();
|
|
20
|
-
fileMutex = new _fileMutex.default(directory, lockFileName,
|
|
18
|
+
fileMutex = new _fileMutex.default(directory, lockFileName, fileDeletionTimeoutConfig);
|
|
21
19
|
});
|
|
22
20
|
describe('acquire', () => {
|
|
23
|
-
it('should create directory if it does not exist', async () => {
|
|
24
|
-
_fs.existsSync.mockReturnValue(false);
|
|
25
|
-
await fileMutex.createDirectoryIfNotExist();
|
|
26
|
-
expect(_fs.mkdirSync).toHaveBeenCalledWith(directory, {
|
|
27
|
-
recursive: true
|
|
28
|
-
});
|
|
29
|
-
});
|
|
30
21
|
it('should create the lock file if it does not exist', async () => {
|
|
31
|
-
_fs.existsSync.mockImplementation(filePath => filePath === authFile ? false : false);
|
|
32
22
|
_fs.writeFileSync.mockImplementation(() => {});
|
|
33
23
|
await fileMutex.acquire();
|
|
34
24
|
expect(_fs.writeFileSync).toHaveBeenCalledWith(fileMutex.lockFilePath, 'locked');
|
|
35
25
|
});
|
|
36
|
-
it('should resolve immediately if auth file exists', async () => {
|
|
37
|
-
_fs.existsSync.mockImplementation(filePath => filePath === authFile);
|
|
38
|
-
await fileMutex.acquire();
|
|
39
|
-
expect(_fs.existsSync).toHaveBeenCalledWith(authFile);
|
|
40
|
-
});
|
|
41
26
|
it('should wait for lock file deletion if it exists', async () => {
|
|
42
27
|
_fs.existsSync.mockImplementation(filePath => filePath === fileMutex.lockFilePath);
|
|
43
28
|
_fs.watch.mockImplementation((dir, callback) => {
|
|
@@ -88,9 +73,7 @@ describe('FileMutex', () => {
|
|
|
88
73
|
_fs.unlinkSync.mockImplementation(() => {
|
|
89
74
|
throw new Error(errorMessage);
|
|
90
75
|
});
|
|
91
|
-
|
|
92
|
-
await fileMutex.release();
|
|
93
|
-
expect(console.error).toHaveBeenCalledWith(`Error deleting lock file: ${errorMessage}`);
|
|
76
|
+
await expect(fileMutex.release()).rejects.toThrow(errorMessage);
|
|
94
77
|
});
|
|
95
78
|
});
|
|
96
79
|
});
|