Проблема с выполнением действий в новом окне с использованием Selenium Webdriver с java

Я работаю над Selenium с java, я открываю драйвер, меняю его прокси и делаю какие-то действия, когда я пытался переключиться на другое окно и менять его прокси, действий не происходило, он показал эту ошибку

java.lang.NullPointerException: Cannot invoke "org.openqa.selenium.SearchContext.findElement(org.openqa.selenium.By)" because "this.searchContext" is null

если это кто-то, кто уже работал с переключением на окна и сменой прокси, пожалуйста, помогите

Я попытался использовать метод swith().to, но не смог изменить прокси, поэтому попытался использовать другой драйвер.

Код, Первый драйвер:

Proxy proxy = new Proxy();
proxy.setHttpProxy("http://" + proxyy);
proxy.setSslProxy("http://" + proxyy);
ChromeOptions options = new ChromeOptions();
options.addArguments("start-maximized");
options.setCapability("proxy", proxy);
driver = new ChromeDriver(options);
randomSleep();
driver.get(JDD.url);
driver.manage().window().maximize();

Второй водитель:

Proxy proxy = new Proxy();
proxy.setHttpProxy("http://" + "104.227.100.66:8147");
proxy.setSslProxy("http://" + "104.227.100.66:8147");
ChromeOptions options = new ChromeOptions();
options.addArguments("start-maximized");
options.setCapability("proxy", proxy);
driver2 = new ChromeDriver(options);
randomSleep();
driver2.get(JDD.url);
driver2.manage().window().maximize();
profil("djfbadhz", "s9djq1ri28fz");
driver2.getWindowHandle(); 

Где твой код?

hfontanez 31.10.2022 16:10

Прокси прокси = новый прокси(); proxy.setHttpProxy("http://" + proxyy); proxy.setSslProxy("http://" + proxyy); Опции ChromeOptions = новые ChromeOptions(); options.addArguments («начало максимизировано»); options.setCapability("прокси", прокси); драйвер = новый ChromeDriver (параметры); случайный сон(); driver.get(JDD.url); driver.manage().window().maximize();

kadouri zakariae 31.10.2022 16:13

и для второго водителя

kadouri zakariae 31.10.2022 16:14

Прокси прокси = новый прокси(); proxy.setHttpProxy("http://" + "104.227.100.66:8147"); proxy.setSslProxy("http://" + "104.227.100.66:8147"); Опции ChromeOptions = новые ChromeOptions(); options.addArguments («начало максимизировано»); options.setCapability("прокси", прокси); driver2 = новый ChromeDriver (параметры); случайный сон(); driver2.get(JDD.url); driver2.manage().window().maximize(); профиль("djfbadhz", "s9djq1ri28fz"); driver2.getWindowHandle();

kadouri zakariae 31.10.2022 16:14

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

hfontanez 31.10.2022 16:56
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
1
5
74
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Поскольку вы не предоставили воспроизводимый код, я просто приведу простой пример того, как переключать вкладки с помощью Selenium 4 (и JUnit 5). Если вы используете Selenium 3, способ сделать это почти такой же. Я могу предоставить соответствующий пример, если вам это нужно.

import static org.junit.jupiter.api.Assertions.assertNotEquals;

import java.time.Duration;

import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;

public class ChromeTest {
    
    @Test
    void helloWorldTest () {
        System.setProperty("webdriver.chrome.driver",
            "F:/drivers/chromedriver.exe");
        WebDriver driver = new ChromeDriver();
        driver.get("https://www.google.com");
        driver.manage().window().maximize();
        String firstTabHandle = driver.getWindowHandle(); // save the first tab handle

        // Open a new tab in the same browser session
        WebDriver newTab = driver.switchTo().newWindow(WindowType.TAB);
        newTab.get("https://www.msn.com/");
        String secondTabHandle = driver.getWindowHandle(); // save the new tab handle

        assertNotEquals(firstTabHandle, secondTabHandle); // not needed.. test the handles are different if you would like
        sleep(driver);
        driver.switchTo().window(firstTabHandle); // switch back to first tab
        sleep(driver);
        driver.switchTo().window(secondTabHandle); // switch back to new tab
        sleep(driver);
        driver.quit(); // end your browser session
    }
    
    private void sleep (WebDriver driver) {
        new WebDriverWait(driver, Duration.ofSeconds(3))
            .until(ExpectedConditions.visibilityOfElementLocated(By.xpath("//body")));
    }
}

Может ли веб-драйвер получить доступ к окну, управляемому другим веб-драйвером?

Насколько мне известно, единственный способ сделать это — использовать драйвер, созданный из того же сеанса. Вы не можете начать два независимых сеанса и передать управление другому водителю (насколько мне известно).

При вызове driver.switchTo().window(String windowHandle) возвращается веб-драйвер, фокусирующийся на только что созданном окне. ОДНАКО, это тот же самый случай, когда «водитель» вызывал switchTo().window(). Поэтому не имеет значения, использовали ли вы возвращенный драйвер или исходный драйвер, поскольку они одинаковы. Честно говоря, я не знаю, почему этот метод вообще возвращает объект. Тем не менее, когда я провел этот тест с использованием возвращенного драйвера, тест был более стабильным. Когда я использовал один и тот же исходный экземпляр, он, как правило, больше сбоил для NoSuchElement во время второй итерации. Я знаю, что это можно исправить с помощью соответствующих WebDriverWait, но мне это показалось интересным.

Чтобы имитировать тот факт, что этот драйвер может взаимодействовать с любым окном, я создал тест ниже. Тест передает три входных данных для повторения и использует эти строки для поиска как в Yahoo (исходное окно), так и в Google (новое окно); все это делается со вторым (новым) драйвером. Этот курс действий не является необходимым. Конечно, каждый драйвер может взаимодействовать с любым окном, которое он создал. Однако, чтобы взаимодействовать со страницей, она должна содержать фокус.

Что это значит в связи с использованием прокси? Я не знаю. Все, что я знаю, это то, что

  1. С сеансом браузера может взаимодействовать один и только один драйвер.
  2. Прокси (наряду с другими параметрами) устанавливаются до начала сеанса и не могут быть изменены после начала сеанса.
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.junit.jupiter.api.Assertions.assertNotEquals;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.fail;

import java.time.Duration;

import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ValueSource;
import org.openqa.selenium.By;
import org.openqa.selenium.Keys;
import org.openqa.selenium.Proxy;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;

public class ChromeTest {
    private static WebDriver driver;
    
    @BeforeAll
    static void setup () {
        System.setProperty("webdriver.chrome.driver",
            "F:/drivers/chromedriver.exe");
        driver = new ChromeDriver();
        driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(5));
    }
    
    @AfterAll
    static void teardown () {
        if (driver != null) {
            driver.quit();
        }
    }
    
    @ParameterizedTest
    @ValueSource(strings = {"dog", "cat", "birds"})
    void simulateCodeTest (String input) {
        driver.get("https://www.yahoo.com");
        driver.manage().window().maximize();
        
        String originalWindow = driver.getWindowHandle();
        WebDriver newWindowDriver = driver.switchTo().newWindow(WindowType.WINDOW);
        newWindowDriver.get("https://www.google.com");
        String newWindowHandle = newWindowDriver.getWindowHandle();
        newWindowDriver.switchTo().window(originalWindow);
        assertTrue(originalWindow.equals(newWindowDriver.getWindowHandle()));
        
        newWindowDriver.switchTo().window(newWindowHandle);
        WebElement searchField = new WebDriverWait(newWindowDriver,
            Duration.ofSeconds(5), Duration.ofMillis(10))
                .until(ExpectedConditions
                    .elementToBeClickable(By.xpath("//input[@title='Search']")));
        new Actions(newWindowDriver).sendKeys(searchField, input)
            .sendKeys(Keys.ENTER).perform();
        
        newWindowDriver.switchTo().window(originalWindow);
        searchField = new WebDriverWait(newWindowDriver, Duration.ofSeconds(5),
            Duration.ofMillis(10))
                .until(ExpectedConditions
                    .elementToBeClickable(By.xpath("//input[@name='p']")));
        new Actions(newWindowDriver).sendKeys(searchField, input)
            .sendKeys(Keys.ENTER).perform();
        WebElement searchButton =
            newWindowDriver.findElement(By.xpath("//button[@type='submit']"));
        searchButton.click();
    }
}

Мне нужно переключаться между окнами, а не вкладками, а также менять прокси. Спасибо за ваш ответ

kadouri zakariae 01.11.2022 11:29

@kadourizakariae Чтобы переключить окна, просто измените WindowType. Я не верю, что «прокси» повлияет на код. Вы пробовали это? Кроме того, при устранении неполадок вы начинаете с удаления всего ненужного. Затем вы можете интегрировать их позже один за другим. И поскольку ваш код неполный и невоспроизводимый, это лучшее, что я могу вам предложить.

hfontanez 01.11.2022 13:36

@kadourizakariae Если вы попробуете это и оно сработает, вы можете изменить свой вопрос, и мы сможем поработать над прокси-частью.

hfontanez 01.11.2022 13:38

как поменять прокси второго окна?

kadouri zakariae 01.11.2022 15:24

@kadourizakariae Остальной код работал?

hfontanez 01.11.2022 15:28

Может быть, вы можете предоставить мне оба прокси, если они общедоступны. Честно говоря, я не вижу проблем с прокси, так как это совершенно независимые сеансы. Любая проблема может быть связана с прокси, а не с окном браузера. Но я могу ошибаться.

hfontanez 01.11.2022 17:03

@kadourizakariae Мы можем пообщаться в LinkedIn, если хотите. На всякий случай я хотел бы обратить ваше внимание на одну вещь: если вы пытаетесь использовать windowHandle одного окна, чтобы указать драйверу, управляющему другим окном, переключиться на него, это невозможно. Дескрипторы окон уникальны для сеанса браузера. Следовательно, оконные дескрипторы для драйвера1 не будут существовать в сеансе, контролируемом драйвером2, и наоборот. На самом деле, я не вижу допустимого варианта использования, когда вы позволили бы второму драйверу взять на себя сеанс браузера, контролируемый другим драйвером. Selenium не был разработан таким образом.

hfontanez 01.11.2022 17:53

@kadourizakariae Я знаю, что это может быть не тот ответ, который вы искали, но если это правильный ответ на то, что, как я думаю, вы пытаетесь сделать. Тем не менее, я был бы признателен, если бы вы выбрали этот ответ как лучший (нажав на галочку), как только вы убедитесь, что то, что я здесь утверждаю, верно.

hfontanez 01.11.2022 18:01

Другие вопросы по теме