I am working on Selenium with java, I open a driver change its proxy and do some actions, when I tried to switch to another window and change its proxy the actions don't happened, it showed this error
java.lang.NullPointerException: Cannot invoke "org.openqa.selenium.SearchContext.findElement(org.openqa.selenium.By)" because "this.searchContext" is null
if their is someone who has already worked with switching to windows and change proxy please help
I tried to use the method swith().to but I couldn't change the proxy so I tried to use another driver.
The code, First driver:
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();
Second driver:
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();
CodePudding user response:
Since you haven't provided reproducible code, I am just going to provide a simple example on how to switch tabs using Selenium 4 (and JUnit 5). If you are using Selenium 3, the way to do it is almost the same. I can provide an appropriate example if you require it.
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")));
}
}
Can a web driver gain access to a window controlled by another web driver?
To my knowledge, the only way to do this is by using a driver created from the same session. You cannot start two independent sessions and hand off control to the other driver (to the best of my knowledge).
When invoking driver.switchTo().window(String windowHandle)
, a web driver is returned that has focus on the newly created window. HOWEVER, this is the same instance as the "driver" used to call switchTo().window()
. Therefore, whether you used the returned driver or the original driver is immaterial, since they the same. Honestly, I don't know why this method returns an object at all. That said, when I ran this test using the returned driver, the test was more stable. When I used the same original instance, it tended to fail more for NoSuchElement
during the second iteration. I know this could be fixed with the appropriate WebDriverWait
, but I found this interesting.
To simulate the fact that this driver can interact with either window, I created the test below. The test passes three inputs to iterate over, and uses these strings to search on both Yahoo (original window) and Google (new window); all of which is done with the second (new) driver. This course of action is not necessary. Of course, each driver can interact with whichever window they created. However, in order to interact with a page, it needs to contain focus.
What does this mean related to using proxies? I do not know. All I know is that
- A browser session can be interacted with by one and only one driver
- Proxies (along with other options) are set before the session starts and cannot be changed after the session has begun.
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();
}
}