Я работаю над 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();
Прокси прокси = новый прокси(); proxy.setHttpProxy("http://" + proxyy); proxy.setSslProxy("http://" + proxyy); Опции ChromeOptions = новые ChromeOptions(); options.addArguments («начало максимизировано»); options.setCapability("прокси", прокси); драйвер = новый ChromeDriver (параметры); случайный сон(); driver.get(JDD.url); driver.manage().window().maximize();
и для второго водителя
Прокси прокси = новый прокси(); 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();
Я добавил ваш код в исходный вопрос. Этого может быть недостаточно, чтобы быть воспроизводимым.




Поскольку вы не предоставили воспроизводимый код, я просто приведу простой пример того, как переключать вкладки с помощью 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 (новое окно); все это делается со вторым (новым) драйвером. Этот курс действий не является необходимым. Конечно, каждый драйвер может взаимодействовать с любым окном, которое он создал. Однако, чтобы взаимодействовать со страницей, она должна содержать фокус.
Что это значит в связи с использованием прокси? Я не знаю. Все, что я знаю, это то, что
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();
}
}
Мне нужно переключаться между окнами, а не вкладками, а также менять прокси. Спасибо за ваш ответ
@kadourizakariae Чтобы переключить окна, просто измените WindowType. Я не верю, что «прокси» повлияет на код. Вы пробовали это? Кроме того, при устранении неполадок вы начинаете с удаления всего ненужного. Затем вы можете интегрировать их позже один за другим. И поскольку ваш код неполный и невоспроизводимый, это лучшее, что я могу вам предложить.
@kadourizakariae Если вы попробуете это и оно сработает, вы можете изменить свой вопрос, и мы сможем поработать над прокси-частью.
как поменять прокси второго окна?
@kadourizakariae Остальной код работал?
Может быть, вы можете предоставить мне оба прокси, если они общедоступны. Честно говоря, я не вижу проблем с прокси, так как это совершенно независимые сеансы. Любая проблема может быть связана с прокси, а не с окном браузера. Но я могу ошибаться.
@kadourizakariae Мы можем пообщаться в LinkedIn, если хотите. На всякий случай я хотел бы обратить ваше внимание на одну вещь: если вы пытаетесь использовать windowHandle одного окна, чтобы указать драйверу, управляющему другим окном, переключиться на него, это невозможно. Дескрипторы окон уникальны для сеанса браузера. Следовательно, оконные дескрипторы для драйвера1 не будут существовать в сеансе, контролируемом драйвером2, и наоборот. На самом деле, я не вижу допустимого варианта использования, когда вы позволили бы второму драйверу взять на себя сеанс браузера, контролируемый другим драйвером. Selenium не был разработан таким образом.
@kadourizakariae Я знаю, что это может быть не тот ответ, который вы искали, но если это правильный ответ на то, что, как я думаю, вы пытаетесь сделать. Тем не менее, я был бы признателен, если бы вы выбрали этот ответ как лучший (нажав на галочку), как только вы убедитесь, что то, что я здесь утверждаю, верно.
Где твой код?