You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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 callback parameter in your step, you must call it inside the then() 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), but by.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 executeScript finds one of them. Double-check your HTML for duplicate roomWidthInput IDs.

内容的提问来源于stack exchange,提问作者M. Paulikas

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 06:35:37