Skip to content

Commit e4297d1

Browse files
author
DavertMik
committed
fixed pw tests
1 parent 792ce21 commit e4297d1

File tree

11 files changed

+104
-71
lines changed

11 files changed

+104
-71
lines changed

lib/command/check.js

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -70,12 +70,17 @@ export default async function (options) {
7070
if (codecept) {
7171
try {
7272
codecept.loadTests()
73+
const files = codecept.testFiles
7374
const mocha = Container.mocha()
74-
mocha.files = codecept.testFiles
75+
mocha.files = files
7576
mocha.loadFiles()
76-
mocha.suite.suites.forEach(suite => {
77-
numTests += suite.tests.length
78-
})
77+
78+
for (const suite of mocha.suite.suites) {
79+
if (suite && suite.tests) {
80+
numTests += suite.tests.length
81+
}
82+
}
83+
7984
if (numTests > 0) {
8085
checks.tests = true
8186
} else {
@@ -103,7 +108,7 @@ export default async function (options) {
103108
if (!Object.keys(helpers).length) throw new Error('No helpers found')
104109
// load helpers
105110
for (const helper of Object.values(helpers)) {
106-
if (helper._init) helper._init()
111+
if (helper._init) await helper._init()
107112
}
108113
checks.helpers = true
109114
} catch (err) {

lib/helper/Playwright.js

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -548,6 +548,14 @@ class Playwright extends Helper {
548548
if (this.options.colorScheme) contextOptions.colorScheme = this.options.colorScheme
549549
this.contextOptions = contextOptions
550550
if (!this.browserContext || !restartsSession()) {
551+
if (!this.browser) {
552+
if (this.options.manualStart) {
553+
this.debugSection('Manual Start', 'Browser not started - skipping context creation')
554+
return // Skip context creation when manualStart is true
555+
} else {
556+
throw new Error('Browser not started. This should not happen.')
557+
}
558+
}
551559
this.debugSection('New Session', JSON.stringify(this.contextOptions))
552560
this.browserContext = await this.browser.newContext(this.contextOptions) // Adding the HTTPSError ignore in the context so that we can ignore those errors
553561
}
@@ -882,6 +890,9 @@ class Playwright extends Helper {
882890
* @param {object} [contextOptions] See https://playwright.dev/docs/api/class-browser#browser-new-context
883891
*/
884892
async _createContextPage(contextOptions) {
893+
if (!this.browser) {
894+
throw new Error('Browser not started. Call _startBrowser() first or disable manualStart option.')
895+
}
885896
this.browserContext = await this.browser.newContext(contextOptions)
886897
const page = await this.browserContext.newPage()
887898
targetCreatedHandler.call(this, page)

lib/helper/WebDriver.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import promiseRetry from 'promise-retry'
77
import { includes as stringIncludes } from '../assert/include.js'
88
import { urlEquals, equals } from '../assert/equal.js'
99
import store from '../store.js'
10-
import { debug } from '../output.js'
10+
import output from '../output.js'
1111
import { empty } from '../assert/empty.js'
1212
import { truth } from '../assert/truth.js'
1313
import { xpathLocator, fileExists, decodeUrl, chunkArray, convertCssPropertiesToCamelCase, screenshotOutputFolder, getNormalizedKeyAttributeValue, modifierKeys } from '../utils.js'
@@ -1772,7 +1772,7 @@ class WebDriver extends Helper {
17721772
try {
17731773
await elem.moveTo({ xOffset, yOffset })
17741774
} catch (e) {
1775-
debug(e.message)
1775+
output.debug(e.message)
17761776
}
17771777
}
17781778

lib/helper/scripts/blurElement.js

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,17 @@
1-
module.exports.blurElement = (element, context) => {
1+
export const blurElement = (element, context) => {
22
const clientSideBlurFn = el => {
3-
el.blur();
4-
};
3+
el.blur()
4+
}
55

66
try {
77
// Puppeteer
8-
context.evaluate(clientSideBlurFn, element);
8+
context.evaluate(clientSideBlurFn, element)
99
} catch (e) {
1010
// WebDriver
1111
try {
12-
context.execute(clientSideBlurFn, element);
12+
context.execute(clientSideBlurFn, element)
1313
} catch (err) {
1414
// ignore
1515
}
1616
}
17-
};
17+
}

lib/helper/scripts/focusElement.js

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,17 @@
1-
module.exports.focusElement = (element, context) => {
1+
export const focusElement = (element, context) => {
22
const clientSideFn = el => {
3-
el.focus();
4-
};
3+
el.focus()
4+
}
55

66
try {
77
// Puppeteer
8-
context.evaluate(clientSideFn, element);
8+
context.evaluate(clientSideFn, element)
99
} catch (e) {
1010
// WebDriver
1111
try {
12-
context.execute(clientSideFn, element);
12+
context.execute(clientSideFn, element)
1313
} catch (err) {
1414
// ignore
1515
}
1616
}
17-
};
17+
}
Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,20 @@
1-
module.exports.highlightElement = (element, context) => {
1+
export const highlightElement = (element, context) => {
22
const clientSideHighlightFn = el => {
3-
const style = '0px 0px 4px 3px rgba(255, 0, 0, 0.7)';
4-
const prevStyle = el.style.boxShadow;
5-
el.style.boxShadow = style;
6-
setTimeout(() => el.style.boxShadow = prevStyle, 2000);
7-
};
3+
const style = '0px 0px 4px 3px rgba(255, 0, 0, 0.7)'
4+
const prevStyle = el.style.boxShadow
5+
el.style.boxShadow = style
6+
setTimeout(() => (el.style.boxShadow = prevStyle), 2000)
7+
}
88

99
try {
1010
// Puppeteer
11-
context.evaluate(clientSideHighlightFn, element).catch(err => console.error(err));
11+
context.evaluate(clientSideHighlightFn, element).catch(err => console.error(err))
1212
} catch (e) {
1313
// WebDriver
1414
try {
15-
context.execute(clientSideHighlightFn, element);
15+
context.execute(clientSideHighlightFn, element)
1616
} catch (err) {
1717
// ignore
1818
}
1919
}
20-
};
20+
}
Lines changed: 34 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,64 +1,64 @@
11
function isElementClickable(element) {
22
if (!element.getBoundingClientRect || !element.scrollIntoView || !element.contains || !element.getClientRects || !document.elementFromPoint) {
3-
return false;
3+
return false
44
}
55

66
const getOverlappingElement = (element, context = document) => {
7-
const elemDimension = element.getBoundingClientRect();
8-
const x = elemDimension.left + (element.clientWidth / 2);
9-
const y = elemDimension.top + (element.clientHeight / 2);
7+
const elemDimension = element.getBoundingClientRect()
8+
const x = elemDimension.left + element.clientWidth / 2
9+
const y = elemDimension.top + element.clientHeight / 2
1010

11-
return context.elementFromPoint(x, y);
12-
};
11+
return context.elementFromPoint(x, y)
12+
}
1313

1414
const getOverlappingRects = (element, context = document) => {
15-
const rects = element.getClientRects();
16-
const rect = rects[0];
17-
const x = rect.left + (rect.width / 2);
18-
const y = rect.top + (rect.height / 2);
15+
const rects = element.getClientRects()
16+
const rect = rects[0]
17+
const x = rect.left + rect.width / 2
18+
const y = rect.top + rect.height / 2
1919

20-
return context.elementFromPoint(x, y);
21-
};
20+
return context.elementFromPoint(x, y)
21+
}
2222

2323
const getOverlappingElements = (element, context) => {
24-
return [getOverlappingElement(element, context), getOverlappingRects(element, context)];
25-
};
24+
return [getOverlappingElement(element, context), getOverlappingRects(element, context)]
25+
}
2626

2727
const isOverlappingElementMatch = (elementsFromPoint, element) => {
2828
if (elementsFromPoint.some(elementFromPoint => elementFromPoint === element || element.contains(elementFromPoint))) {
29-
return true;
29+
return true
3030
}
3131

32-
let elementsWithShadowRoot = [...new Set(elementsFromPoint)];
33-
elementsWithShadowRoot = elementsWithShadowRoot.filter(elem => elem && elem.shadowRoot && elem.shadowRoot.elementFromPoint);
32+
let elementsWithShadowRoot = [...new Set(elementsFromPoint)]
33+
elementsWithShadowRoot = elementsWithShadowRoot.filter(elem => elem && elem.shadowRoot && elem.shadowRoot.elementFromPoint)
3434

35-
let shadowElementsFromPoint = [];
35+
let shadowElementsFromPoint = []
3636
for (const shadowElement of elementsWithShadowRoot) {
37-
shadowElementsFromPoint.push(...getOverlappingElements(element, shadowElement.shadowRoot));
37+
shadowElementsFromPoint.push(...getOverlappingElements(element, shadowElement.shadowRoot))
3838
}
39-
shadowElementsFromPoint = [...new Set(shadowElementsFromPoint)];
40-
shadowElementsFromPoint = shadowElementsFromPoint.filter(element => !elementsFromPoint.includes(element));
39+
shadowElementsFromPoint = [...new Set(shadowElementsFromPoint)]
40+
shadowElementsFromPoint = shadowElementsFromPoint.filter(element => !elementsFromPoint.includes(element))
4141

4242
if (shadowElementsFromPoint.length === 0) {
43-
return false;
43+
return false
4444
}
4545

46-
return isOverlappingElementMatch(shadowElementsFromPoint, element);
47-
};
46+
return isOverlappingElementMatch(shadowElementsFromPoint, element)
47+
}
4848

49-
const isElementInViewport = (element) => {
50-
const rect = element.getBoundingClientRect();
49+
const isElementInViewport = element => {
50+
const rect = element.getBoundingClientRect()
5151

52-
const windowHeight = (window.innerHeight || document.documentElement.clientHeight);
53-
const windowWidth = (window.innerWidth || document.documentElement.clientWidth);
52+
const windowHeight = window.innerHeight || document.documentElement.clientHeight
53+
const windowWidth = window.innerWidth || document.documentElement.clientWidth
5454

55-
const vertInView = (rect.top <= windowHeight) && ((rect.top + rect.height) > 0);
56-
const horInView = (rect.left <= windowWidth) && ((rect.left + rect.width) > 0);
55+
const vertInView = rect.top <= windowHeight && rect.top + rect.height > 0
56+
const horInView = rect.left <= windowWidth && rect.left + rect.width > 0
5757

58-
return (vertInView && horInView);
59-
};
58+
return vertInView && horInView
59+
}
6060

61-
return element.disabled !== true && isElementInViewport(element) && isOverlappingElementMatch(getOverlappingElements(element), element);
61+
return element.disabled !== true && isElementInViewport(element) && isOverlappingElementMatch(getOverlappingElements(element), element)
6262
}
6363

64-
module.exports = isElementClickable;
64+
export default isElementClickable

lib/mocha/factory.js

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ class MochaFactory {
1717
mocha = new Mocha(Object.assign(config, opts))
1818
output.process(opts.child)
1919
mocha.ui(scenarioUiFunction)
20-
20+
2121
// Manually trigger UI setup for globals to be available in ESM context
2222
// This ensures Feature, Scenario, Before, etc. are available immediately
2323
if (mocha.suite && mocha.suite.emit) {
@@ -51,13 +51,30 @@ class MochaFactory {
5151
// remove feature files
5252
mocha.files = mocha.files.filter(file => !file.match(/\.feature$/))
5353

54-
Mocha.prototype.loadFiles.call(mocha, fn)
54+
// In ESM context, tests may already be loaded during codecept initialization
55+
// Only call original Mocha loadFiles if no suites exist yet
56+
if (mocha.suite.suites.length === 0) {
57+
try {
58+
Mocha.prototype.loadFiles.call(mocha, fn)
59+
} catch (e) {
60+
// If original loadFiles fails (e.g., ESM compatibility issues),
61+
// skip it since tests may already be loaded through codecept
62+
if (e.message.includes('getStatus') || e.message.includes('ESM')) {
63+
console.warn('Skipping Mocha.prototype.loadFiles due to ESM compatibility issues')
64+
} else {
65+
throw e
66+
}
67+
}
68+
}
5569

5670
// add ids for each test and check uniqueness
5771
const dupes = []
5872
let missingFeatureInFile = []
5973
const seenTests = []
6074
mocha.suite.eachTest(test => {
75+
if (!test) {
76+
return // Skip undefined tests
77+
}
6178
const name = test.fullTitle()
6279
if (seenTests.includes(test.uid)) {
6380
dupes.push(name)

test/acceptance/codecept.Playwright.coverage.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
const TestHelper = require('../support/TestHelper')
1+
import TestHelper from '../support/TestHelper.js'
22

3-
module.exports.config = {
3+
export const config = {
44
tests: './*_test.js',
55
timeout: 10000,
66
output: './output',

test/acceptance/codecept.Testcafe.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
const TestHelper = require('../support/TestHelper')
1+
import TestHelper from '../support/TestHelper.js'
22

3-
module.exports.config = {
3+
export const config = {
44
tests: './*_test.js',
55
timeout: 10000,
66
output: './output',

0 commit comments

Comments
 (0)