testcafe: In headless with CDP, actions like click/typeText do not work from time to time. Fine without headless
What is your Scenario?
Trying to switch from old testcafe versions with proxy to CDP as the proxy works too slow and unstable, but there are a lot of issues with CDP.
What is the Current behavior?
In headless, actions like click/typeText do not work from time to time. Fine without headless.
If I just add few more the same lines as
await t.typeText(Selector("[data-testid='destination-container']"), "Warsaw", {replace: true});
it works fine, but after from time to time fails on
What is the Expected behavior?
to work đ
What is your public website URL? (or attach your complete example)
What is your TestCafe test code?
import { ClientFunction, RequestHook, Selector } from 'testcafe';
import page from './page-model';
export class ProdHook extends RequestHook {
constructor() {
super(/(devexpress.github.io)/, {
includeHeaders: true,
includeBody: true
});
}
async onRequest(event) {
event.requestOptions.headers['automatic-qa'] = "true";
}
async onResponse() {
}
}
export async function removeTargetAttributes() {
return ClientFunction(() => {
const selector = document.querySelectorAll("div[data-testid='availability-cta'] a");
selector.forEach(el => el.removeAttribute("target"));
})();
}
async function booking(t) {
await t.navigateTo("https://booking.com/");
await t.wait(4000);
await t.typeText(Selector("[data-testid='destination-container']"), "Warsaw", {replace: true});
await t.click(Selector("[data-testid='autocomplete-result']").withText(/Warsaw/));
await t.click(Selector("td[role='gridcell'] span[class='b21c1c6c83']").nth(10));
await t.click(Selector("td[role='gridcell'] span[class='b21c1c6c83']").nth(15));
await t.click(Selector("button[type='submit'] span[class='e57ffa4eb5']"));
await t.wait(5000);
await t.eval(() => {
const selector = document.querySelectorAll("div[data-testid='availability-cta'] a");
selector.forEach(el => el.removeAttribute("target"));
});
await t.wait(3000);
await removeTargetAttributes();
console.log(`Count is: ${await Selector("div[data-testid='availability-cta'] a[target]").count}`);
await t.click(Selector("div[data-testid='availability-cta'] a").nth(10));
await t.expect(Selector("div[id='hp_hotel_name']", {timeout: 10000}).visible).ok({timeout: 10000});
}
fixture`A set of examples that illustrate how to use TestCafe API`
test('Text typing basics', async t => {
const asd = new ProdHook();
await t.addRequestHooks(asd);
await t.navigateTo("https://devexpress.github.io/testcafe/example");
await t
.typeText(page.nameInput, 'Peter') // Type name
.typeText(page.nameInput, 'Paker', { replace: true }) // Replace with last name
.typeText(page.nameInput, 'r', { caretPos: 2 }) // Correct last name
.expect(page.nameInput.value).eql('Parker'); // Check result
await booking(t);
});
test('Click an array of labels and then check their states', async t => {
const asd = new ProdHook();
await t.addRequestHooks(asd);
await booking(t);
await t.navigateTo("https://devexpress.github.io/testcafe/example");
for (const feature of page.featureList) {
await t
.click(feature.label)
.expect(feature.checkbox.checked).ok({timeout: 10000});
}
});
test('Dealing with text using keyboard', async t => {
const asd = new ProdHook();
await t.addRequestHooks(asd);
await t.navigateTo("https://devexpress.github.io/testcafe/example");
await t
.typeText(page.nameInput, 'Peter Parker') // Type name
.click(page.nameInput, { caretPos: 5 }) // Move caret position
.pressKey('backspace') // Erase a character
.expect(page.nameInput.value).eql('Pete Parker') // Check result
.pressKey('home right . delete delete delete') // Pick even shorter form for name
.expect(page.nameInput.value).eql('P. Parker'); // Check result
await t
.typeText(page.nameInput, 'Peter') // Type name
.typeText(page.nameInput, 'Paker', { replace: true }) // Replace with last name
.typeText(page.nameInput, 'r', { caretPos: 2 }) // Correct last name
.expect(page.nameInput.value).eql('Parker'); // Check result
await booking(t);
});
test('Moving the slider', async t => {
const asd = new ProdHook();
await t.addRequestHooks(asd);
await booking(t);
await t.navigateTo("https://devexpress.github.io/testcafe/example");
const initialOffset = await page.slider.handle.offsetLeft;
await t
.click(page.triedTestCafeCheckbox)
.dragToElement(page.slider.handle, page.slider.tick.withText('9'))
.expect(page.slider.handle.offsetLeft).gt(initialOffset);
});
test('Dealing with text using selection', async t => {
const asd = new ProdHook();
await t.addRequestHooks(asd);
await t.navigateTo("https://devexpress.github.io/testcafe/example");
await t
.typeText(page.nameInput, 'Test Cafe')
.selectText(page.nameInput, 7, 1)
.pressKey('delete')
.expect(page.nameInput.value).eql('Tfe'); // Check result
await booking(t);
});
test('Handle native confirmation dialog', async t => {
const asd = new ProdHook();
await t.addRequestHooks(asd);
await t.navigateTo("https://devexpress.github.io/testcafe/example");
await t
.setNativeDialogHandler(() => true)
.click(page.populateButton);
const dialogHistory = await t.getNativeDialogHistory();
await t.expect(dialogHistory[0].text).eql('Reset information before proceeding?');
await t
.click(page.submitButton)
.expect(page.results.innerText).contains('Peter Parker');
await booking(t);
});
test('Pick option from select', async t => {
const asd = new ProdHook();
await t.addRequestHooks(asd);
await t.navigateTo("https://devexpress.github.io/testcafe/example");
await t
.click(page.interfaceSelect)
.click(page.interfaceSelectOption.withText('Both'))
.expect(page.interfaceSelect.value).eql('Both');
await booking(t);
});
test('Filling a form', async t => {
const asd = new ProdHook();
await t.addRequestHooks(asd);
await t.navigateTo("https://devexpress.github.io/testcafe/example");
// Fill some basic fields
await t
.typeText(page.nameInput, 'Bruce Wayne')
.click(page.macOSRadioButton)
.click(page.triedTestCafeCheckbox);
// Let's leave a comment...
await t
.typeText(page.commentsTextArea, "It's...")
.wait(500)
.typeText(page.commentsTextArea, '\ngood');
// I guess, I've changed my mind
await t
.wait(500)
.selectTextAreaContent(page.commentsTextArea, 1, 0)
.pressKey('delete')
.typeText(page.commentsTextArea, 'awesome!!!');
// Let's submit our form
await t
.wait(500)
.click(page.submitButton)
.expect(page.results.innerText).contains('Bruce Wayne');
await booking(t);
});
Your complete configuration file
module.exports = {
"src": "tests",
"pageLoadTimeout": 40000,
"pageRequestTimeout": 45000,
"selectorTimeout": 10000,
disableMultipleWindows: true,
disableNativeAutomation: false,
concurrency: 3,
screenshots: {
path: "./artifacts/screenshots",
takeOnFails: true,
pathPattern: "${DATE}_${TIME}/${TEST}/${FILE_INDEX}_${QUARANTINE_ATTEMPT}.png",
thumbnails: false
},
}
Your complete test report
No response
Screenshots
No response
Steps to Reproduce
described above
TestCafe version
3.1.0-rc.1
Node.js version
v16.19.0
Command-line arguments
npx testcafe chrome/chrome:headless
Browser name(s) and version(s)
No response
Platform(s) and version(s)
MacOS 13.4.1
Other
No response
About this issue
- Original URL
- State: closed
- Created a year ago
- Reactions: 1
- Comments: 16 (7 by maintainers)
@vasilyevi Hi. I tried to research the issue. However, I cannot reproduce it anymore with the latest https://www.npmjs.com/package/testcafe/v/3.2.0 version. The problem with the
Warsaw
autocomplete disappeared and now everything works as expected. As for the issue with Selector, I noticed strange behavior. TheBooking
website renders different markup for the headless and headed modes. You can easily check it if you make screenshots or enable video recording. So the issue with Selector really exists, but not because of TestCafe.Please try to update your TestCafe version to the latest and share your results with us.
I can reproduce the issue with the
Warsaw
autocomplete. I just gave you a couple of recommendations which work in my case. By the way, I managed to reproduce the issue even in headed mode. Weâll research it.Split this issue into three different issues and create a separate thread for each case. It will allow us to process them more efficiently. Also, please prepare a minimal example for each case. Currently, the test code looks very large and not informative.