gpt4 book ai didi

javascript - 如何停止 webdriver 而不导致 Node js 崩溃

转载 作者:太空宇宙 更新时间:2023-11-04 00:20:56 24 4
gpt4 key购买 nike

是否可以在不停止 Node 的情况下停止selenium webdriver?

我有以下问题:我尝试创建一个 API 工具,在收到 get 请求时执行一些 Web 自动化。所以我基本上是通过 Express 对/start 的 get 请求运行 selenium webdriver 。我希望该工具检查不同的元素,当它以某种方式失败时,我希望它停止 selenium,但不停止 Node 实例(因为可以发送新的 get 请求)。

这是我到目前为止的代码:

"use strict";

const webdriver = require('selenium-webdriver'),
Express = require('express'),
By = webdriver.By,
until = webdriver.until,
Keys = webdriver.Key,
app = new Express();

app.get("/automate", (req, res) => {
start(res);
});

function start(res) {
const driver = new webdriver.Builder().forBrowser('chrome').build();

driver.get('https://www.google.com/');

// # --- foo --- #
let errMessage = {pos: "FOO", message: "Ooops friendly robot has some troubles!"}
checkStep("#foo", errMessage);

driver.findElement(By.id("foo"))
.sendKeys("fooz");

// # --- bar --- #
errMessage = {pos: "BAR", message: "Ooops friendly robot has some troubles!"}
checkStep("#bar", errMessage);

driver.findElement(By.id("bar"))
.sendKeys("baz");

// etc…

function checkStep(selector, errMessage) {
driver.findElement(By.css(selector))
.then(() => {
console.log(`${selector} => found`);
})
.catch(err => {
console.log(`Error: ${err}`);
res.send(errMessage);
driver.quit();
});
}
}

app.get("*", (req, res) => {
res.send("Hello World");
});

// start the server
const port = process.env.PORT || 3000;
const env = process.env.NODE_ENV || 'production';
app.listen(port, err => {
if (err) { return console.error(err); }
console.info(`Server running on http://localhost:${port} [${env}]`);
});

到目前为止,它实际上正在工作,当 selenium 找不到该元素时,API 的响应是正确的。在 Selenium 中我返回:

{
"pos": "FOO",
"message": "Ooops friendly robot has some troubles!"
}

到目前为止一切都很好。但是不幸的是,停止 selenium 也会阻止 Node 运行。

我得到的错误如下:

throw error;
^

WebDriverError: no such session
(Driver info: chromedriver=2.30.477690 (c53f4ad87510ee97b5c3425a14c0e79780cdf262),platform=Ma
c OS X 10.12.5 x86_64)
at WebDriverError

请帮忙,谢谢!

ps:我没有使用 webdriverio,正如你所看到的,我使用这个包:https://www.npmjs.com/package/selenium-webdriver

最佳答案

好的,我成功了。这是一个有点困难的解决方案,但它有效:

使用子进程

基本上,每次应用程序收到对 /automateget 请求时,它现在都会在运行 selenium 脚本的 Node 中创建一个子进程(子进程有点像使用另一个线程。这是一个非常好的 tutorial on child processes ):

index.js

"use strict";

const Express = require('express');
const { spawn } = require('child_process');
const data = require('./data.json');

const app = new Express();

app.get("/automate", (req, res) => {

const child = spawn(
process.execPath,
[`${__dirname}/test.js`, JSON.stringify(data)],
{ stdio: ['inherit', 'inherit', 'inherit', 'pipe'] }
);

child.stdio[3].on('data', data => {
const response = JSON.parse(data.toString());
res.send(response);
console.log(response);
child.kill();
});

});

app.get("*", (req, res) => {
res.send("Hello World");
});

const port = process.env.PORT || 3000;
const env = process.env.NODE_ENV || 'production';
app.listen(port, err => {
if (err) { return console.error(err); }
console.info(`Server running on http://localhost:${port} [${env}]`);
});

测试.js

"use strict";

// hook with argument 3, that is "pipe" from parent
const Net = require('net'),
pipe = new Net.Socket({ fd: 3 });

const data = JSON.parse(process.argv[2]);

const webdriver = require('selenium-webdriver'),
By = webdriver.By,
until = webdriver.until,
Keys = webdriver.Key;

function start() {
const driver = new webdriver.Builder().forBrowser('chrome').build();

driver.get('https://www.google.com/');

// # --- foo --- #
let errMessage = {pos: "lst-ib", message: "Ooops friendly robot has some troubles!"}
checkStep("#lst-ib")
.sendKeys("fooz");

driver.get('https://www.facebook.com/');
driver.get('https://www.google.com/');
driver.get('https://www.facebook.com/');

// # --- bar --- #
errMessage = {pos: "BAR", message: "Ooops friendly robot has some troubles!"}
checkStep("#bar")
.sendKeys("baz");

function checkStep(selector) {
driver.findElement(By.css(selector))
.then(() => {
console.log(`${selector} => found`);
})
.catch(err => {
console.log(`${selector} => not found`);
publish(errMessage);
driver.quit();
});
}
}

function publish(message) {
pipe.write(JSON.stringify(message));
}

start();

它的工作方式就像一个魅力:在每个请求上打开一个新的子进程,如果该子进程发送一些消息,同时也向客户端响应消息,则杀死该子进程。像这样,您可以轻松地同时拥有多个 selenium 实例。

不客气。

ps:如果你讨厌 Selenium 中的所有异步东西 webdriver-sync似乎是一个不错的选择。它基本上将 selenium 代码包装为同步而不是异步。这样我就可以使用 try {} catch {}driver.quit(); 而不会出现后续代码的任何错误。 (但这有一个缺点:它实际上阻塞了你的其他 Nodejs 代码。)

关于javascript - 如何停止 webdriver 而不导致 Node js 崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44609765/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com