Есть отличная удаленная работа для php+codeception+jenkins+allure+docker спецов. 100% remote! Присоединиться к проекту

[Resolved] Завершение профиля FireFox


(Рома Маринский) #1

Как сделать так чтобы созданный профиль не завершался в одном классе и действия дальше продолжали выполняться из другого класса


Ну допустим я закомментировал строку driver.quit();
Но как в другом классе подхватить созданный профиль FireFox и продолжить действия из другого класса?


(sidelnikovmike) #2

По хорошему нужно контролировать, чтобы был только один инстанс вебдрайвера в тестах. и шарить его между классами.


(Рома Маринский) #3

Приведи пожалуйста пример, как это делать?)


(sidelnikovmike) #4

ну примеров можно написать кучу.
Для начала советую почитать для примера про паттерн синглтон (вот например ссылка с хабра про него). Можно в таком классе хранить инстанс и от него плясать. В этом же классе сделать метод для “убийства” драйвера. То есть везде вы будете использовать конструкцию типа “DriverSingleton.getDrtiver()”


(Рома Маринский) #5

Благодарю, сегодня попробую


(Sergey Korol) #6

Не забывайте отписываться в теме о решении. :wink:
И если чье-то сообщение оказалось вам полезным, не забываем ставить лайк.


(Рома Маринский) #7

А где эта тема “О решении”?


(Sergey Korol) #8

Вы создали раз тему, не отписав помогло ли решение. Вы создали вторую - текущую тему.
Возможно кто-то в будущем столкнется с аналогичной проблемой и ваше подтверждение будет в помощь для ее решения. А лайки могут служить способом фильтрации сообщений для концентрации лишь на нужном результате.


(Рома Маринский) #9

Как установить статус решения вопроса “Resolved”?


(Sergey Korol) #10

Для вас - никак. Модераторы просматривают темы, и если автора какой-то ответ удовлетворил (и он потрудился об этом сообщить) - маркируют тему как resolved / решено.


(Рома Маринский) #11

Написал класс типа “синглтон” и наследовался от него.
Дальше мне нужно вызвать метод другого класса, но если я использую конструкцию типа

ClassA pov = new ClassA ();
pov.methodClassB();

То у меня отображается ошибка:

java.lang.NullPointerException

Ошибка к строкам driver.findElement(By.id("limit")).click(); и pov.methodClassB();

Что я неправильно делаю? Методы класса А и класса В типа void


(Рома Маринский) #12

Я попробовал конструкцию с использованием приведения типов:

private ClassA pov;
...
((ClassA) pov).methodClassB();

Теперь у дочернего класса нет ошибок. Но осталась ошибка NullPointerException к строке ((ClassA) pov).methodClassB();


(sidelnikovmike) #13

Не надо наследоваться от синглтона. Он - хранилище драйвера с методами set и get и переменной, в которой инстанс хранится. Методы - статические.

Nullpointer - а вы изначально проинициализировали обьект driver?

С приведением - не усложняйте. У вас в задаче просто нужно в нужный момент вызвать Singleton.setDriver(driverInstance) и потрм везде вызывать Singleton.getDriver() и все должно работать.


(Рома Маринский) #14

Не могу разобраться как написать set и get методы для драйвера в синглтоне

public static Singleton instance;
public static synchronized Singleton getInstance() {
    if (instance == null) {
        instance = new Singleton();
    }
    return instance;
}

public static void setUp() throws Exception {
    driver = new FirefoxDriver();
    driver.get("http://trafficapp.softproject.com.ua/");
    driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
}

public static void tearDown() throws Exception {
    driver.quit();
}

(sidelnikovmike) #15
public class DriverSingleton { 
   private static WebDriver driver; 
   public static WebDriver getDriver() { 
      return driver;
   } 
   public static void setDriver(WebDriver driverToSet) {
        driver = driverToSet;
   }
 }

и где то в классе в вашем:

driver = new FirefoxDriver();
DriverSingleton.setDriver(driver);

ну и где угодно в тестах:

DriverSingleton.getDriver().findElements(blalbalba);

Разумеется пример мой - это просто пример. Он не очень хорош, но демонстрирует принцип работы и хранения инстанса драйвера в одном месте. Можно в этом же классе-хранилище реализовать инициализацию драйвера и тому подобную функциональность.


(Рома Маринский) #16

Спасибо за помощь @sidelnikovmike решение было совсем простым

Так и так, решение проблемы “Завершение профиля webdriver”, если вам нужно чтобы после выполнения действий одного класса дальше продолжали выполняться действия других классов, иначе говоря исполнение сложных сценариев, вам потребуется:
Создайте класс определены все объекты и переменные которые вам потребуются в других классах (чтобы не плодить повторяющиеся строки)

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.*;
import org.openqa.selenium.firefox.FirefoxDriver;
    
public class BeforeTest {
        public WebDriver driver;
        public String username;
        public String password;
        WebElement campaignInputBox, userInputBox, passInputBox;

Далее пишем такую очень важную и простую конструкцию :smile:

 public BeforeTest(){
        driver = new FirefoxDriver();
        driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS); 
    }

Ну и остальные методы которые будут использоваться у вас, например:

public boolean isElementPresent(By by) {
        try {
            driver.findElements(by);
            return true;
        } catch (org.openqa.selenium.NoSuchElementException e) {
            return false;
        }
}

В другом классе пишете такое:

import static org.junit.Assert.*;
import org.openqa.selenium.By;
import java.util.concurrent.TimeUnit;

   //Наследование от нужного класса, где описано создание драйвера, соответствующие методы, объекты и переменные
public class Authorization extends BeforeTest{ 

    public Authorization(){
        this.username = "asd@asd.asd";
        this.password = "111111";
    }

    public void authorization() throws Exception {
        driver.get ("http://site.com/");
        driver.findElement(By.linkText("login")).click();
        userInputBox = driver.findElement(By.id("email"));
        passInputBox = driver.findElement(By.id("password"));

//Type fields
        userInputBox.sendKeys(username);
        passInputBox.sendKeys(password);
        driver.findElement(By.cssSelector("input.btn.btn-primary")).click();
    }
}

В классе который должен далее выполнять действия над сайтом, пишем наследование от соответствующего класса и вызываем его метод. В моём случае я наследуюсь от класса Authorization и вызываю его метод authorization(). Класс будет выглядеть примерно так:

import org.openqa.selenium.By;
import java.util.concurrent.TimeUnit;
import static org.junit.Assert.fail;

public class CreateNewCampaign extends Authorization {

    public void newCampaign() throws Exception {
        authorization(); //вызываем соответствующий метод класса Authorization 
        driver.findElement(By.linkText("New Campaign")).click();

И далее описываем дальнейшие действия:

 while (valueOfScenario < 5) {
                campaignName = "campaign name" + valueOfScenario;
                switch (valueOfScenario) {
                    case 1:
                        driver.findElement(By.id("daily-lim")).click();
                        driver.findElement(By.name("daily_price_value")).clear();
                        driver.findElement(By.name("daily_price_value")).sendKeys("100");
                    case 2:
                        driver.findElement(By.id("campaign-lim")).click();
                        driver.findElement(By.name("campaign_price_value")).clear();
                        driver.findElement(By.name("campaign_price_value")).sendKeys("10000");
                        campaignInputBox = driver.findElement(By.id("campaign_name"));
                        campaignInputBox.sendKeys(campaignName);
                        valueOfScenario += 1;
                        driver.findElement(By.cssSelector("button.btn.btn-primary")).click();
                        for (int second = 0; ; second++) {
                            if (second >= 60) fail("timeout");
                            try {
                                if (isElementPresent(By.linkText("New Campaign"))) break;
                            } catch (Exception e) {
                                return;
                            }
                            Thread.sleep(1000);
                        }
                        driver.findElement(By.linkText("New Campaign")).click();
                        break;
                    case 3:
                        driver.findElement(By.id("daily-lim")).click();
                        driver.findElement(By.name("daily_price_value")).clear();
                        driver.findElement(By.name("daily_price_value")).sendKeys("100");
                    case 4:
                        valueOfScenario += 1;
                        campaignInputBox = driver.findElement(By.id("campaign_name"));
                        campaignInputBox.sendKeys(campaignName);
                        driver.findElement(By.cssSelector("button.btn.btn-primary")).click();
                        for (int second = 0; ; second++) {
                            if (second >= 60) fail("timeout");
                            try {
                                if (isElementPresent(By.linkText("New Campaign"))) break;
                            } catch (Exception e) {
                                return;
                            }
                            Thread.sleep(1000);
                        }
                        driver.findElement(By.linkText("New Campaign")).click();
                        break;
                }
            }
        }

Ну и самое главное запуск нашей магии. Создаём ещё один класс, с помощью которого запускаем магию:

import org.junit.Test;

public class Tests {

   CreateNewCampaign create; // класс с последними действиями

    @Test
    public void startTest() throws Exception {
        create = new CreateNewCampaign(); //выделяем память
        create.newCampaign(); //вызываем метод
    }
}

Ну вот как-то так корявенько я это сделал. Далее я буду объединять большое количество классов , проблемы которые будут выявляться дальше, буду описывать в этой или в другом посте со ссылкой на этот.
Буду очень благодарен кто тыкнет пальцем где я слишком извращённо написал код :slight_smile:

P.S. это мой первый опыт в разработке кода на JAVA


(sidelnikovmike) #17

Вы что-то мне кажется перебарщиваете с иерархией классов, с наследованиями.
Почитайте про page object pattern, он сделаем Ваши тесты более красивыми и удобными для поддержки.

Но молодцы, что стараетесь! Для первого раза - хорошо!


(Рома Маринский) #18

Спасибо, почитаю более детально про него. Абсолютно согласен про иерархию классов)
Уже встречал использование page object на stackoverflow. Так что быстро разберусь)