Удаленка для jenkins+selenide+selenoid+allure+docker спецов на 2-3 часа в день. 100% remote! Присоединиться к проекту

Session ID is null. Webdriver error- Cucumber JVM

cucumber
java
webdriver
selenium
Теги: #<Tag:0x00007fedbb1b5200> #<Tag:0x00007fedbb1b4f30> #<Tag:0x00007fedbb1b4da0> #<Tag:0x00007fedbb1b4940>

(Raznoe Raznoe) #1

Bсем привет
Использую Maven JUnit Cucumber JVM
весь код тут https://github.com/raznoe/demka
Имею такие

@search
Feature: Search Google for links
As an internet user
I want to use Google to search for websites
So that I can find them without knowing the URL

Scenario: Search for Facebook
Given I want to go on “Facebook”
When I search on Google “Facebook”
Then I should see the search results for “Facebook”

Scenario: Search for Hotmail
Given I want to go on “Hotmail”
When I search on Google “Hotmail”
Then I should see the search results for “Hotmail”

Scenario: Search for Yandex
Given I want to go on “Yandex”
When I search on Google “Yandex”
Then I should see the search results for “Yandex”

При запуске тестов, запускается все и первый scenario проходит, остальные грохаются - Session ID is null. Using WebDriver after calling quit()?

Driver

public class Driver {

public static WebDriver webdriver;
public static WebDriver getCurrentDriver() {
    if (webdriver == null) {
        webdriver = WebdriverFactory.createWebdriver();
        webdriver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
        webdriver.manage().timeouts().pageLoadTimeout(100, TimeUnit.SECONDS);
    }
    return webdriver;
}

WebDriverFactory

public static WebDriver createWebdriver() {
caps = new DesiredCapabilities();
String seleniumEnvironment = TestRunner.config.get(“seleniumEnvironment”);

    if (seleniumEnvironment.equals("local")) {
        return BrowserFactory.selectLocalBrowser();

Hooks

@Before
public void before(Scenario scenario) throws IOException {
TestRunner.scenario = scenario;
TestRunner.config = FileRead.readProperties();
}

@After
public void after(Scenario scenario)
{
   Driver.webdriver.quit();
}

При запуске тестов, запускается все и первый scenarioпроходит, остальные грохаются error - Session ID is null. Using WebDriver after calling quit()?

Подскажите где накосячил, понимаю сто после запуска первого Driver закрывается и поэтому получаю этот error. Думаю, что косяк идет от public static Webdriver driver, но не могу разобраться если поменять все на, то вылазят ошибки.

Java не мой конек, больше по Ruby, но работодатель хочет так, поэтому выберать не получается.

Подскажите или подкиньте идеи, спасибо


(Pavel Ponomaryov) #2

а как ты хочешь сделать - чтобы браузер не закрывался между тестами или наоборот?


(Raznoe Raznoe) #3

Хочу, чтоб браузер закрывался при прогонке одного scenario и отрывался новый браузер при запуске другого scenario


(Oleksandr Khotemskyi) #4

Вы браузер в постхуке закрыли, а в прехуке не создали -

@Before
public void before(Scenario scenario) throws IOException {
TestRunner.scenario = scenario;
TestRunner.config = FileRead.readProperties();
}

Driver.webdriver.quit(); - не убивает сам java-обьект, и он остается в памяти. Соответственно -

if (webdriver == null) // будет false
и новый драйвер не создается

Вот пример говнокодика который может помочь

public class Driver {

public static WebDriver webdriver;
public static WebDriver getCurrentDriver() {

    if (webdriver == null) {
        webdriver = WebdriverFactory.createWebdriver();
        webdriver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
        webdriver.manage().timeouts().pageLoadTimeout(100, TimeUnit.SECONDS);
    }
    return webdriver;
}

public static void kill() {
    if (webdriver != null) {
        webdriver.quit()
        webdriver = null
    }
}

Тогда в постхуке -

@After
public void after(Scenario scenario)
{
Driver.kill();
}

Код не тестил - но идея думаю понятна.


(Raznoe Raznoe) #5

@xotabu4 спасибо, вопрос, получается что я все равно убиваю браузер, а вот когда переход на новый scenario, почему то @Before не поднимается браузер. Как я понимаю, это действие должно автоматом делаться, а потом уже искать или же надо в прописать @Before Driver.getCurrentDriver?


(Oleksandr Khotemskyi) #6

у вас в before сейчас нет вызова getCurrentDriver() - тут надо смотреть как вы в самих шагах получаете инстанс браузера


(Raznoe Raznoe) #7

@xotabu4 при попадании на степ (When I search on Google “Facebook”) Selenium переходит на GoogleSearch_Action.search(searchCriteria); и там приписано

public class GoogleSearch_Action extends Config{

static WebDriver driver = Driver.getCurrentDriver();

static WebDriverWait wait = new WebDriverWait(driver, 10);

public static void search(String searchCriteria) {

    driver.get(baseUrl);

я так понимаю что static WebDriver driver = Driver.getCurrentDriver();
должно запускать новый instance браузер


#8
  1. было бы неплохо увидеть весь код в одном месте, не очень удобно скролить по теме в поисках кусочков кода,

  2. ты пробовал продебажить код?

driver статическое поле, и оно будет инициализировано при создании класса. Не знаю как там происходит в cucumber, но сдается мне, что после первого .quit () не будет создания драйвера в getCurrentDriver


(Raznoe Raznoe) #9

@olyv код можно увидеть тут https://github.com/raznoe/demka
пробовал продебажить код, когда преходит на второй scenario, то вроде следущий instance брaузерa поднимается, и питается найти Session ID, не находит и падает с ошибкой org.openqa.selenium.NoSuchSessionException: Session ID is null. Using WebDriver after calling quit()?


(Pavel Ponomaryov) #10

Должно запускать, если проверку свою пофиксишь. Сейчас ты только проверяешь на null, но в After хуке не обнуляешь. Всё уже выше написали.


(Raznoe Raznoe) #11

@pavelp я обнуляю в

public static void kill(){
if (webdriver != null){
webdriver.quit();
webdriver = null;
}
}


(Pavel Ponomaryov) #12

Попробуй вынести инициализацию драйвера в @Before. И зачем тебе поле driver в Hooks, если ты его не используешь?


(Raznoe Raznoe) #13

@pavelp
когда переношу

if (webdriver == null) {
webdriver = WebdriverFactory.createWebdriver();
webdriver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
webdriver.manage().timeouts().pageLoadTimeout(100, TimeUnit.SECONDS);
}
return webdriver;

в public void before(Scenario scenario) throws IOException {

получаю error изза return webdriver;

а ведь надо же делать return, но и не могу убрать void

если заменяю на
public WebDriver before(Scenario scenario) throws IOException {

получаю
java.lang.NullPointerException


(Pavel Ponomaryov) #14

Боже, не надо так делать. я имел в виду вызови Driver.getCurrentWebDriver() из своего уже существующего хука before


(Raznoe Raznoe) #15

pardon, так тоже сделал только что и когда подхожу
public static void search(String searchCriteria) {

    driver.get(baseUrl);

то в debug, driver = null и получаю java.lang.NullPointerException


(Pavel Ponomaryov) #16

не надо делать в классе GoogleSearch_Action статическое поле. Доставай инстанс в каждом методе через Driver, или вообще юзай Selenide. Таскать за собой драйвер и постоянно на это отвлекаться - замучаешься


(Raznoe Raznoe) #17

всем(@xotabu4, @pavelp) спасибо за поддержку фиксами и идеями, многому чему научился сегодня.

да пришлось убрать static WebDriver driver = Driver.getCurrentDriver(); со всех classes и работает как часы