登录后保持会话-硒-javascript

时间:2018-11-01 23:48:59

标签: javascript selenium promise automation webdriver

我正在尝试使用Selenium Web驱动程序和node js自动执行几个页面。我能够登录,但是登录后我想使用由Web驱动程序启动的同一会话,以便可以在受会话保护的页面上进行自动测试。这是我的尝试

async function login(){
    Let  d =  await new Builder()
                        .forBrowser('chrome')
                        .build();
    await d.get('https://demo.textdomain.com/')
    await d.findElement(By.id('username')).sendKeys('admin ')
    await d.findElement(By.id('password')).sendKeys('admin');
    await d.findElement(By.css('button[type="submit"]')).click();
    await d.getPageSource().then(function(content) {

            if(content.indexOf('Welcome text') !==-1 ) {
             console.log('Test passed');
             console.log('landing page');
             d.get('https://demo.textdomain.com/landingpage') //this is still going to login page as i cannot use the previous session 
            } else {
                console.log('Test failed');
                return false;
            }
            //driver.quit();
        });

}

login();

我是否在登录后不小心丢弃了浏览器。

4 个答案:

答案 0 :(得分:4)

通过类似SQA StackExchange的问题,您可以存储和恢复当前会话的cookie:

使用Javascript:

// Storing cookies:
driver.manage().getCookies().then(function (cookies) {
    allCookies = cookies;
}); 

// Restoring cookies:
for (var key in allCookies) {
    driver.manage().addCookie(key, allCookies[key]);
}

答案 1 :(得分:3)

您可能只在处理计时问题。硒很快移动。比您作为用户进行交互的方式要快得多。因此,它通常以似乎无法预测的方式起作用。但这仅仅是因为Selenium的运行速度比您作为用户的速度快得多。为了解决此问题,您应该充分利用Selenium的内置driver.wait。例如:

const button = driver.wait(
  until.elementLocated(By.id('my-button')), 
  20000
);

button.click();

以上内容一直等到ID为my-button的按钮出现在DOM中,然后单击它。最多等待20000毫秒,但是只要按钮可用,操作就会结束。

因此,在您的情况下,如果在用户成功登录后仍有可用的东西,则可以等待该元素,然后再进入代码中的新页面。

顺便说一句,我也不确定为什么要使用getPageSource()?这似乎是获得所需内容的一种非常笨拙的方法。那不是您可以获取其中内容的元素中的内容吗?

我写了一篇有关How to write reliable browser tests using Selenium and Node.js的文章,它可以帮助您更详细地理解文章中的上述代码示例,以及可以用来可靠地等待浏览器中各种条件的其他技术。

答案 2 :(得分:2)

我相信您的问题没有正确地等待登录完成。

Selenium不会等待异步操作完成,而是移至下一行,因此当您请求页面源时,很有可能登录服务器上的登录操作未完成,结果是不是您的期望。

您必须明确告知Selenium等待,因此您需要在登录名和检查用户是否登录的代码之间添加一些代码,出于这种假设,请增加10秒钟的超时时间。

如果这对您有用,您就不想浪费时间,因此您需要等待页面上的某些元素由于登录而发生更改,例如,您需要等待状态(或可见性)标头中的用户照片(如果已在DOM中)。

另外,我不确定“ getPageSource”函数的行为方式,它可以使用现有页面,还是可以要求新的副本。

我建议您使用其他方法通过检查DOM来测试用户是否已登录。

答案 3 :(得分:0)

我建议在其他Web驱动程序实例中首次登录后重新使用会话cookie。

首先存储cookie:

var cookieValue = firstWebDriver.Manage().Cookies.GetCookieNamed(name:"cookie_name");

然后,您可以将其传递给任何WebDriver实例,对其进行设置并驱动该Web应用程序,因为它是同一用户使用不同的浏览器实例:

anotherWebDriver.Manage().Cookies.AddCookie(new Cookie(name:"cookie_name", value:cookieValue));

如果要使用相同的浏览器实例,则必须对其进行同步,因为WebDriver调用通常不是线程安全的,并且probalby经常会导致异常(例如, stale ,因为元素更改或找不到,因为一个Web驱动程序导航到了另一个页面。

然后,我建议仅对下一个实例使用窗口句柄,而不关心会话。第一个打开,最后一个关闭会话(计算引用的句柄),并确保一次只有一个驱动程序使用此句柄。您还可以创建新的浏览器窗口,这将保留会话并为您提供新的句柄:

var handle = firstWebDriver.CurrentWindowHandle;
otherWebDriver.SwitchTo().Window(handle);

我用C#编写了代码,但是应该很容易适应JavaScript。