Cucumber Protractor调用element的then()后超时及Angular2元素定位加#无效求助
Troubleshooting Your Cucumber-Protractor Issues
Hey there, let's tackle these two Cucumber-Protractor headaches you're dealing with in your Angular 2 app—they're common issues, so we've got this!
1. Timeout After Calling then() on a Protractor Element Promise
That timeout when chaining then() to your element selection is almost always tied to unhandled asynchronous flow or quirks with Protractor's Angular synchronization. Here's what to fix:
- Don’t leave Cucumber hanging: If you’re using the
callbackparameter in your step, you must call it inside thethen()block. Leaving it outside means Cucumber will wait indefinitely for the step to finish, triggering a timeout. - Ditch callbacks for async/await: Nested
then()blocks get messy fast, and Protractor supports async/await natively. This makes your code cleaner and way less prone to async-related timeouts. - Wait for the element to be ready: Sometimes the timeout happens because the element isn’t fully loaded when you try to interact with it. Use Protractor’s Expected Conditions to wait for visibility or clickability first.
Here’s a revised version of your step using async/await:
// Don't forget to import ExpectedConditions at the top! const { ExpectedConditions: EC } = require('protractor'); When('I select my input box', async () => { const inputbox = element(by.css('#roomWidthInput')); console.log('inputBox promise set'); // Wait 5 seconds for the input to become visible await browser.wait(EC.visibilityOf(inputbox), 5000, 'Input box never loaded'); // Execute your script and await the result const elementFromScript = await browser.executeScript("return document.getElementById('roomWidthInput');"); console.log('info', elementFromScript); });
2. Protractor Can’t Recognize Element Even With # Prefix in CSS Selector
It’s odd that executeScript can find the element but Protractor’s element() can’t—this usually means the element lives in a context Protractor doesn’t monitor by default. Try these fixes:
- Use
by.id()directly:by.css('#roomWidthInput')can hit edge cases (like special characters in the ID), butby.id('roomWidthInput')is purpose-built for ID selection and more reliable in Protractor. - Check for Shadow DOM: If your input is inside a Web Component’s shadow DOM, standard selectors won’t reach it. Access the shadow root first:
const shadowHost = element(by.css('your-shadow-host-element')); const inputbox = await shadowHost.getShadowRoot().element(by.id('roomWidthInput')); - Temporarily disable Angular sync: If the element is part of a non-Angular third-party widget, Protractor’s Angular synchronization might wait for non-existent Angular hooks. Toggle it off for this step:
await browser.waitForAngularEnabled(false); const inputbox = element(by.id('roomWidthInput')); // Do your interaction here await browser.waitForAngularEnabled(true); // Re-enable for future Angular steps - Confirm the ID is unique: Duplicate IDs in the DOM can confuse Protractor’s selectors, even if
executeScriptfinds one of them. Double-check your HTML for duplicateroomWidthInputIDs.
内容的提问来源于stack exchange,提问作者M. Paulikas
相关产品推荐
相关产品推荐

