-
Notifications
You must be signed in to change notification settings - Fork 678
Description
What is your Scenario?
When attempting to run tests using
testcafe .\tests\pagetests\FleetElement-Tests.ts
tests on my local laptop I keep getting an error message
ERROR Cannot establish one or more browser connections.
2 of 2 browser connections have not been established:
- edge:headless
- edge:headless
If I run a single test using .only I do not get the error
If I configure browser to point to "browsers": "path:C:\\Program Files (x86)\\Microsoft\\Edge\\Application\\msedge.exe" I do not get the error
What is the Current behavior?
When attempting to run tests using
testcafe .\tests\pagetests\FleetElement-Tests.ts
tests on my local laptop I keep getting an error message
ERROR Cannot establish one or more browser connections.
2 of 2 browser connections have not been established:
- edge:headless
- edge:headless
What is the Expected behavior?
Tests should start and run
What is the public URL of the test page? (attach your complete example)
fixtureFleetElement Tests
.pagehttp://the-internet.herokuapp.com;
What is your TestCafe test code?
import { Selector, t as controller } from 'testcafe';
export class FleetElement {
public webElement: Selector;
public controller: TestController;
constructor(locator: string | ((...args: any[]) => Node | Node[] | NodeList | HTMLCollection) | Selector | NodeSnapshot
| SelectorPromise, options?: SelectorOptions) {
this.webElement = Selector(locator, options);
}
public get exists(): Promise<boolean> {
return this.webElement.exists;
}
public get count(): Promise<number> {
return this.webElement.count;
}
public get isChecked(): Promise<boolean> {
return this.webElement.checked;
}
public get isVisible(): Promise<boolean> {
return this.webElement.visible;
}
public get hasFocus(): Promise<boolean> {
return this.webElement.focused;
}
public get isSelected(): Promise<boolean> {
return this.webElement.selected;
}
public hasAttribute(attributeName: string): Promise<boolean> {
return this.webElement.hasAttribute(attributeName);
}
public get getTagName(): Promise<string> {
return this.webElement.tagName;
}
public getStyleValue(propertyName: string): Promise<string> {
return this.webElement.getStyleProperty(propertyName);
}
public getAttributeValue(attributeName: string): Promise<string> {
return this.webElement.getAttribute(attributeName);
}
public get getSelectedIndex(): Promise<number> {
return this.webElement.selectedIndex;
}
public get getInnerText(): Promise<string> {
return this.webElement.innerText;
}
public get getTextContent(): Promise<string> {
return this.webElement.textContent;
}
public get getScrollHeight(): Promise<number> {
return this.webElement.scrollHeight;
}
public get getInnerHeight(): Promise<number> {
return this.webElement.clientHeight;
}
public get getInnerWidth(): Promise<number> {
return this.webElement.clientWidth;
}
public get getScrollWidth(): Promise<number> {
return this.webElement.scrollWidth;
}
public get getValue(): Promise<string> {
return this.webElement.value;
}
public async isValid(): Promise<boolean> {
if (await this.webElement.getAttribute('aria-invalid') === 'true' || (await this.webElement.getAttribute('class')).includes('invalid')) {
return false;
}
return true;
}
public async isRequired(): Promise<boolean> {
if (await this.webElement.getAttribute('aria-required') === 'true') {
return true;
}
return false;
}
public async getMaxLength(): Promise<string> {
return this.webElement.getAttribute('maxlength');
}
public async getTitle(): Promise<string> {
return this.webElement.getAttribute('title');
}
public async isExpanded(): Promise<boolean> {
return (await this.webElement.getAttribute('aria-expanded') === "true") ||
(await this.webElement.getAttribute('class')).includes('mat-expanded');
}
public async isDisabled(): Promise<boolean> {
return (await this.webElement.hasAttribute('disabled')) || (await this.webElement.getAttribute('aria-disabled') === 'true') || (await this.webElement.getAttribute('disabled') === 'true')
|| (await this.webElement.getAttribute('class')).includes('mat-checkbox-disabled') || (await this.webElement.getAttribute('class')).includes('mat-disabled')
|| (await this.webElement.getAttribute('class')).includes('disabled') || (await this.webElement.getAttribute('class')).includes('mdc-switch--disabled')
|| (await this.webElement.getAttribute('ng-reflect-disabled') === 'true')
|| ((await this.webElement.tagName) === 'button' && (await this.webElement.getAttribute('role')) === 'switch');
}
public async isReadOnly(): Promise<boolean> {
return (await this.webElement.getAttribute('readonly') === "true")
}
public async isTextFieldBlank(): Promise<boolean> {
return (await this.webElement.value === '');
}
public async isDropDownFieldEmpty(): Promise<boolean> {
return (await this.webElement.getAttribute('class')).includes('empty');
}
public async getInputLabelText(): Promise<string> {
return this.webElement.parent('div').find('label').child('mat-label').innerText;
}
public async isCheckboxChecked(): Promise<boolean> {
return (await this.webElement.getAttribute('class')).includes('checked');
}
public async isTooltipTextCorrect(tooltipText: string): Promise<boolean> {
return (await this.webElement.parent('mat-form-field').getAttribute('title') === (tooltipText));
}
public async isDropDownFieldValueCorrect(fieldValue: string): Promise<boolean> {
return ((await this.webElement.find("span").innerText).trim() === fieldValue);
}
public getBoundingClientRectPropertyValue(propertyName: string): Promise<number> {
return this.webElement.getBoundingClientRectProperty(propertyName);
}
public withAttribute(attributeName: string | RegExp, attrValue?: string | RegExp): FleetElement {
return new FleetElement(this.webElement.withAttribute(attributeName, attrValue));
}
public withText(text: string): FleetElement;
public withText(re: RegExp): FleetElement;
public withText(identifier: string | RegExp): FleetElement {
if (typeof identifier === 'string') {
return new FleetElement(this.webElement.withText(identifier));
}
return new FleetElement(this.webElement.withText(identifier));
}
public withIndex(index: number): FleetElement {
return new FleetElement(this.webElement.nth(index));
}
public withExactText(text: string): FleetElement {
return new FleetElement(this.webElement.withExactText(text));
}
public filterOnCssSelector(cssSelector: string): FleetElement {
return new FleetElement(this.webElement.filter(cssSelector));
}
public filterOnFunction(filterFn: (node: Element, idx: number) => boolean,
dependencies?: { [key: string]: any }): FleetElement {
return new FleetElement(this.webElement.filter(filterFn, dependencies));
}
public withChild(): FleetElement;
public withChild(index: number): FleetElement;
public withChild(cssSelector: string): FleetElement;
public withChild(identifier?: number | string): FleetElement {
if (identifier === undefined) {
return new FleetElement(this.webElement.child());
} else if (typeof identifier === 'number') {
return new FleetElement(this.webElement.child(identifier));
} else {
return new FleetElement(this.webElement.child(identifier));
}
}
public withChildFunction(filterFn: (node: Element, idx: number, originNode: Element) => boolean,
dependencies?: { [key: string]: any }): FleetElement {
return new FleetElement(this.webElement.child(filterFn, dependencies));
}
public withParent(): FleetElement;
public withParent(index: number): FleetElement;
public withParent(cssSelector: string): FleetElement;
public withParent(identifier?: number | string): FleetElement {
if (identifier === undefined) {
return new FleetElement(this.webElement.parent());
} else if (typeof identifier === 'number') {
return new FleetElement(this.webElement.parent(identifier));
} else {
return new FleetElement(this.webElement.parent(identifier));
}
}
public withParentFunction(filterFn: (node: Element, idx: number, originNode: Element) => boolean,
dependencies?: { [key: string]: any }): FleetElement {
return new FleetElement(this.webElement.parent(filterFn, dependencies));
}
public withSibling(): FleetElement;
public withSibling(index: number): FleetElement;
public withSibling(cssSelector: string): FleetElement;
public withSibling(identifier?: number | string): FleetElement {
if (identifier === undefined) {
return new FleetElement(this.webElement.sibling());
} else if (typeof identifier === 'number') {
return new FleetElement(this.webElement.sibling(identifier));
} else {
return new FleetElement(this.webElement.sibling(identifier));
}
}
public withDescendant(cssSelector: string): FleetElement {
return new FleetElement(this.webElement.find(cssSelector));
}
/**call of parent select element to open the drop down and get the option count */
public async getOptionCount(mouseAction?: MouseActionOptions): Promise<number> {
const parentSelect = new FleetElement(this.webElement);
await parentSelect.click(mouseAction);
return new FleetElement('div').withChild('mat-option[role="option"]').count;
}
/**call off parent select element to open the dropdown and select the option */
public async selectOption(text: string, mouseAction?: MouseActionOptions): Promise<void>;
public async selectOption(index: number, mouseAction?: MouseActionOptions): Promise<void>;
public async selectOption(identifier: string | number, mouseAction?: MouseActionOptions): Promise<void> {
const select = new FleetElement(this.webElement);
const option = new FleetElement('div').withChild('mat-option[role="option"]');
await select.click(mouseAction);
if (typeof identifier === 'string') {
const foundOption = option.withExactText(identifier);
await foundOption.click(mouseAction);
} else {
const foundOption = option.withIndex(identifier)
await foundOption.click(mouseAction);
}
}
// Validates an <input> or <textarea> has expected label, maxLength, and value
public async areInputPropertiesCorrect(expectedLabel: string, expectedMaxLength: string,
expectedValue: string): Promise<boolean> {
return ((await this.webElement.getAttribute('placeholder') === expectedLabel || await this.webElement.parent('div').find('label').child('mat-label').innerText === expectedLabel)
&& (await this.webElement.value === expectedValue)
&& (await this.webElement.getAttribute('maxlength') === expectedMaxLength));
}
public async selectRadioButtonValue(optionName: string, mouseAction?: MouseActionOptions): Promise<void> {
const radioSelect = new FleetElement(this.webElement).withDescendant(`mat-radio-button`).withDescendant(`input[value="${optionName}"]`);
await radioSelect.click(mouseAction);
}
public async setNumberOfDays(numberOfDays: string): Promise<string> {
await controller.click(this.webElement);
await controller.pressKey('ctrl+a delete');
await controller.typeText(this.webElement, numberOfDays)
const numberOfDaysFieldvalue = await this.webElement.value;
return numberOfDaysFieldvalue;
}
public openWindow(url: string): WindowDescriptorPromise {
return controller.openWindow(url);
}
public getCurrentWindow(): WindowDescriptorPromise {
return controller.getCurrentWindow();
}
public switchToWindow(window: WindowDescriptorPromise): TestControllerPromise;
public switchToWindow(window: any): TestControllerPromise;
public switchToWindow(filterFn: (data: WindowFilterData) => boolean): TestControllerPromise;
public switchToWindow(identifier: WindowDescriptorPromise | ((fnc: WindowFilterData) => boolean) | any): TestControllerPromise {
if (typeof identifier === 'object') {
return controller.switchToWindow(identifier);
}
else {
return controller.switchToWindow(identifier)
}
}
public switchToParentWindow(): TestControllerPromise {
return controller.switchToParentWindow();
}
public switchToPreviousWindow(): TestControllerPromise {
return controller.switchToPreviousWindow();
}
public closeWindow(): TestControllerPromise;
public closeWindow(window: WindowDescriptorPromise): TestControllerPromise;
public closeWindow(window: any): TestControllerPromise;
public closeWindow(identifier?: WindowDescriptor): TestControllerPromise {
if (typeof identifier === 'undefined') {
return controller.closeWindow(identifier);
}
else {
return controller.closeWindow(identifier);
}
}
public click(mouseAction?: MouseActionOptions): TestControllerPromise {
return controller.click(this.webElement, mouseAction);
}
public rightClick(mouseAction?: MouseActionOptions): TestControllerPromise {
return controller.click(this.webElement, mouseAction);
}
public doubleClick(mouseAction?: MouseActionOptions): TestControllerPromise {
return controller.doubleClick(this.webElement, mouseAction);
}
public dragElementByOffset(dragOffsetX: number, dragOffsetY: number,
mouseAction?: MouseActionOptions): TestControllerPromise {
return controller.drag(this.webElement, dragOffsetX, dragOffsetY, mouseAction);
}
public dragToElement(destinationSelector: FleetElement,
mouseAction?: MouseActionOptions): TestControllerPromise {
return controller.dragToElement(this.webElement, destinationSelector.webElement, mouseAction);
}
public hover(mouseAction?: MouseActionOptions): TestControllerPromise {
return controller.hover(this.webElement, mouseAction);
}
public selectText(startPos?: number, endPos?: number, speed?: ActionOptions): TestControllerPromise {
return controller.selectText(this.webElement, startPos, endPos, speed);
}
public selectTextAreaContent(startLine?: number,
startPos?: number,
endLine?: number,
endPos?: number,
speed?: ActionOptions): TestControllerPromise {
return controller.selectTextAreaContent(this.webElement, startLine, startPos, endLine, endPos, speed);
}
public selectEditableContent(endSelector: FleetElement,
speed?: ActionOptions): TestControllerPromise {
return controller.selectEditableContent(this.webElement, endSelector.webElement, speed)
}
public async clearField(): Promise<void> {
await controller.click(this.webElement);
await controller.pressKey('ctrl+a delete');
}
public typeText(text: string,
typeAction?: TypeActionOptions): TestControllerPromise {
return controller.typeText(this.webElement, text, typeAction);
}
public upload(filePath: string | string[]): TestControllerPromise {
return controller.setFilesToUpload(this.webElement, filePath);
}
public clearUpload(): TestControllerPromise {
return controller.clearUpload(this.webElement);
}
public takeElementScreenshot(path?: string, options?: TakeElementScreenshotOptions): TestControllerPromise {
return controller.takeElementScreenshot(this.webElement, path, options);
}
}
========================================================
import { FleetElement } from "../../src/FleetElement";
fixtureFleetElement Tests
.pagehttp://the-internet.herokuapp.com;
test('Drag And Drop test', async controller => {
await new FleetElement('a[href="/drag_and_drop"]').click();
const secondElement = new FleetElement('#column-b');
await new FleetElement('#column-a').dragToElement(secondElement);
const bothElements = new FleetElement('[class="column"]')
await controller.expect(await bothElements.withIndex(0).getInnerText).eql("B")
});
test('Checkbox tests', async controller => {
await new FleetElement('a[href="/checkboxes"]').click();
const checkedBox = new FleetElement('#checkboxes').withChild('input').withIndex(1);
await controller.expect(await checkedBox.hasAttribute('checked')).eql(true)
});
test('Open window tests', async controller => {
await new FleetElement('a[href="/windows"]').click().openWindow('/windows/new');
const header = await new FleetElement('h3').getInnerText;
await controller.expect(header).eql('New Window');
});
test('Get current window tests', async controller => {
await new FleetElement('a[href="/windows"]').click().openWindow('/windows/new');
const window = await new FleetElement('h3').getCurrentWindow();
await controller.expect(window).ok()
});
test('Switch window tests', async controller => {
const homepageElement = await new FleetElement('a[href="/windows"]');
const homepageWindow = homepageElement.getCurrentWindow;
const newWindowpageElement = await new FleetElement('a[href="/windows"]');
const newWindow = await newWindowpageElement.openWindow('/windows/new');
const switchedNewWindow = await homepageElement.switchToWindow(newWindow).getCurrentWindow();
await controller.expect(switchedNewWindow).ok();
await controller.expect(homepageWindow).ok();
await controller.expect(newWindowpageElement).ok();
});
test('Multi window support', async controller => {
const homepageElement = await new FleetElement('a[href="/windows"]');
const newWindowpage1Element = await new FleetElement('a[href="/windows"]');
const newWindow1 = await newWindowpage1Element.openWindow('/windows/new');
const switchedNewWindow1 = await homepageElement.switchToWindow(newWindow1).getCurrentWindow();
const newWindowpage2Element = await new FleetElement('a[href="/windows"]');
const newWindow2 = await newWindowpage2Element.openWindow('/windows/new');
const switchedNewWindow2 = await homepageElement.switchToWindow(newWindow2).getCurrentWindow();
const newWindowpage3Element = await new FleetElement('a[href="/windows"]');
const newWindow3 = await newWindowpage3Element.openWindow('/windows/new');
const switchedNewWindow3 = await homepageElement.switchToWindow(newWindow3).getCurrentWindow();
const prevWindow3 = await newWindowpage3Element.switchToPreviousWindow().getCurrentWindow();
const prevWindow2 = await newWindowpage2Element.switchToPreviousWindow().getCurrentWindow();
const prevWindow1 = await newWindowpage1Element.switchToPreviousWindow().getCurrentWindow();
await controller.expect(switchedNewWindow1).ok();
await controller.expect(switchedNewWindow2).ok();
await controller.expect(switchedNewWindow3).ok();
await controller.expect(prevWindow3).ok();
await homepageElement.closeWindow(newWindowpage3Element).getCurrentWindow();
await controller.expect(prevWindow2).ok();
await homepageElement.closeWindow(newWindowpage3Element).getCurrentWindow();
await controller.expect(prevWindow1).ok();
await homepageElement.closeWindow(newWindowpage3Element).getCurrentWindow();
});
Your complete configuration file
{
"browsers": "edge:headless",
"concurrency": 1,
"hostname": "localhost",
"selectorTimeout": 40000,
"assertionTimeout": 40000,
"pageLoadTimeout": 120000,
"pageRequestTimeout": 120000,
"skipJsErrors": true,
"speed": 0.8,
"screenshots": {
"takeOnFails": true,
"pathPattern": "${BROWSER}/${FIXTURE}/${TEST}.png"
}
}
Your complete test report
ERROR Cannot establish one or more browser connections.
1 of 1 browser connections have not been established:
- edge:headless
Hints:
- Increase the Browser Initialization Timeout if its value is too low (currently: 2 minutes for local browsers and 6 minutes for remote browsers). The timeout determines how long TestCafe waits for browsers to be ready.
- The error can also be caused by network issues or remote device failure. Make sure that your network connection is stable and you can reach the remote device.
Screenshots
No response
Steps to Reproduce
- In a terminal run testcafe .\tests\pagetests\FleetElement-Tests.ts
TestCafe version
3.7.2
Node.js version
22.20.0
Command-line arguments
testcafe .\tests\pagetests\FleetElement-Tests.ts
Browser name(s) and version(s)
Edge Version 142.0.3595.80
Platform(s) and version(s)
Windows 11 Enterprise version 10.0.26200 Build 26200
Other
Other members of my team are having the same issue. Tried enabling native automation.