找不到按钮元素,但可以找到兄弟元素

时间:2018-01-31 22:20:32

标签: javascript selenium-chromedriver

Html在这里(注意 - 这部分嵌套在iframe中):

<div data-reactroot="">
  <div class="src-scenes-authenticated-components-sign-in-form-styles__main--I0vWu">
    <div class="src-scenes-authenticated-components-sign-in-form-styles__featureList--2RQdY"></div>
    <button class="src-components-button-styles__defaultButtonTheme--2-m2n src-components-button-styles__button--2hZHd">
      <div class="src-components-button-styles__content--28F4J">
         <div class="src-scenes-authenticated-components-sign-in-form-styles__signInButton--3AQAr">Sign In</div> 
      </div>  
    </button>
    <div class="src-scenes-authenticated-components-sign-in-form-styles__footer--1kMhz"></div>
  </div>
</div>

以下是我尝试定位<button>元素的方法:

.elementByXPath('/html/body/div[2]/div/div') // parent div of button .elementByXPath('/html/body/div[2]/div/div/div[1]') // first child .elementByXPath('/html/body/div[2]/div/div/div[2]') // sibling AFTER button .elementByXPath('/html/body/div[2]/div/div/button') // error - NoSuchElement

我尝试使用child::button找到该按钮,following-sibling::button ...仍然没有运气。我还试图找到嵌套在按钮中的<div>元素。仍然无法找到它。我也在找到第一个孩子后尝试找到按钮元素(因为它是第二个孩子),仍然得到相同的错误(NoSuchElement)。

我尝试的另一件事是.moveTo() ......这确实有效,但当我点击它时没有任何反应。

我错过了什么?

这里有完整的测试代码:

import wd, { asserters } from 'wd';
import configureLogging from './helpers/logging';
import { setup, config } from './helpers/config.js';

const {
  capabilities,
  testTimeout } = config;

export default function owaChromeLogin() {
  describe('Login flow via OWA for Chrome', function() {
    this.timeout(testTimeout);
    let driver;
    setup();

    before(function() {
      driver = wd.promiseChainRemote();
      configureLogging(driver);

      let desired = {
        ...capabilities.owa.chrome
      };

      return driver.init(desired);
    });

    after(function() {
      return driver;
      .quit();
    });


    // this is all to log into OWA AND the plugin
    it('should go to OWA and log in', function() {
      return driver
      .get('https://outlook.office365.com/owa/')
      .elementById('i0116') // username
      .type('****@****.onmicrosoft.com')
      .elementById('idSIButton9') // 'next' button
      .click()
      .waitForElementById('i0118', asserters.isDisplayed, 10000, 500) // password field...flaky - StaleElementReference
      .type('****')
      .elementById('idSIButton9') // 'sign in' button
      .click()
      .elementById('idSIButton9') // 'yes' button to stay signed in
      .click()
      .waitForElementByXPath('//*[@id="primaryContainer"]/div[4]/div/div[1]/div/div[4]/div[1]/div/div[1]/div/div/div[2]/div/button', asserters.isDisplayed, 5000, 300)
      .should.eventually.exist;
    });

    it('should click New Email', function() {
      return driver
      .elementByXPath('//*[@id="primaryContainer"]/div[4]/div/div[1]/div/div[4]/div[1]/div/div[1]/div/div/div[1]/div/button[1]')
      .click()
      .waitForElementByXPath('//*[@id="primaryContainer"]/div[4]/div/div[1]/div/div[4]/div[3]/div/div[5]/div[1]/div/div[3]/div[4]/div/div[1]/div[2]/div[3]/div[2]/div[1]/button[1]', asserters.isDisplayed, 5000, 300)
      .should.eventually.exist;
    });

    it('should be able to open the Outreach plugin', function() {
      return driver
      // wait for AND click on Outreach logo button (bottom RH)
      .waitForElementByXPath('//*[@id="primaryContainer"]/div[4]/div/div[1]/div/div[4]/div[3]/div/div[5]/div[1]/div/div[3]/div[4]/div/div[1]/div[2]/div[3]/div[2]/div[2]/div/div/div/div/div[1]/div/div/button', asserters.isDisplayed, 5000, 300)
      .click()
      .waitForElementByXPath('/html/body/div[12]/div/div/div/div/div/div/ul/li[5]', asserters.isDisplayed, 5000, 300) // "Open Outreach"
      .click()
      // need to target items within iframe
      .waitForElementById('exttsp0', asserters.isDisplayed, 10000, 300) // iframe (parent)
      .elementByXPath('/html/body/div[2]/div/div') // parent div of button
      .elementByXPath('/html/body/div[2]/div/div/div[1]') // first child
      .elementByXPath('/html/body/div[2]/div/div/button') // error - NoSuchElement
    });
  });
}

1 个答案:

答案 0 :(得分:0)

解决!在看了我的第100次自动测试运行之后,我意识到.waitForElementByXPath('xpath of parent element')的输出提供了几个元素而不是一个元素。这是在加载之前存在的iframe之前发生的。所以,我需要在尝试定位iframe之前添加一个时间延迟(睡眠) - .frame(0) ...因为它全部在我的第一个iframe中),然后我能够通过id定位按钮。我知道使用.sleep()并不理想,但我打算稍后再回过头来。

总的来说,这是测试方法的样子:

wd.addPromiseChainMethod('getSignInButton', function() {
  return this
    .sleep(3000)
    .frame(0)
    .waitForElementById('parentDiv', asserters.isDisplayed, 10000, 300)
    .elementById('signInButon')
    .click()
});