使用 mocha 和 selenium-webdriver js 获得有意义的堆栈跟踪

Ale*_*502 6 javascript selenium node.js async-await selenium-webdriver

当我在 JavaScript selenium 测试中找不到元素时,它并没有给我一个简单的方法来找出哪一行失败:

下面是一个例子:

// test.js

const webdriver = require('selenium-webdriver');
const Builder = webdriver.Builder;
const By = webdriver.By;

describe('web driver', function() {
  let driver;
  beforeEach(function() {
    return new Builder().forBrowser('chrome').build().then(function(_driver) {
      driver = _driver;
    });
  });

  it('should always be able to find the element', function() {
    return driver.findElement(By.name('test-element'));
  });

  afterEach(function() {
    return driver.quit();
  });
});
Run Code Online (Sandbox Code Playgroud)

当像这样运行时:

npm install selenium-webdriver@4.0.0-alpha.1
npm install mocha@6.0.2
nvm install 8.15.1
nvm use 8.15.1
node_modules/.bin/mocha test.js
Run Code Online (Sandbox Code Playgroud)

我收到以下错误:

     NoSuchElementError: no such element: Unable to locate element: {"method":"css selector","selector":"*[name="test-element"]"}
  (Session info: chrome=72.0.3626.121)
  (Driver info: chromedriver=2.42.591071 (0b695ff80972cc1a65a5cd643186d2ae582cd4ac),platform=Linux 4.15.0-46-generic x86_64)
      at Object.checkLegacyResponse (node_modules/selenium-webdriver/lib/error.js:585:15)
      at parseHttpResponse (node_modules/selenium-webdriver/lib/http.js:533:13)
      at Executor.execute (node_modules/selenium-webdriver/lib/http.js:468:26)
      at <anonymous>
      at process._tickCallback (internal/process/next_tick.js:189:7
Run Code Online (Sandbox Code Playgroud)

这在这个测试中很容易理解,但在更长的测试中真的很难,因为它没有给我一条测试线,而且我经常不止一次搜索相同的元素。

有没有办法来解决这个问题?

(我的实际测试是使用 async/await,但我没有做这个例子,问题是一样的)

Ale*_*502 0

现在我有了更好的解决方法。

这是一个比我的更复杂的修复: https: //github.com/rundeck/rundeck/pull/6355/files(在这个问题的错误报告中提到https://github.com/SeleniumHQ/selenium/issues/7626

我只是在此包装器中包装对方法的每个调用driverhttps://gitlab.com/alex028502/binary-tools/-/tree/master/ip-address/fix-selenium-stack-trace

(我认为你至少需要节点 12 才能工作)

function fixSeleniumStackTrace (snippet) {
  const stack = new Error('start of stack trace wrapper').stack;
  try {
    return Promise.resolve(snippet()).catch(function(e) {
      e.stack = e.stack + '\n' + stack;
      throw e;
    });
  } catch (e) {
    e.stack = e.stack + '\n' + stack;
    throw e;
  }
};

Run Code Online (Sandbox Code Playgroud)

像这样

const bodyTag = await fixSeleniumStackTrace(function () {
  return driver.findElement(By.tagName('body'));
});

Run Code Online (Sandbox Code Playgroud)

由于我的大部分电话都是在助手中进行的,所以情况并不像看起来那么糟糕。我只需要将调用包装在我的助手中即可。我可以在版本3中关闭SELENIUM_PROMISE_MANAGER,或者使用版​​本4。