How to switch tab in safari

Hey guys,

I’m facing a prolem, appium cannot switch tab in safari
Here is the situation:
I got webview A , and contains a link to webView B, if i click that link , it goes to B,
But after that, i need to back to A…
Here is my code:
String currentWindow = driver.getWindowHandle();
XXXXXXXXXXXXXXXXXXX
driver.switchTo().window(currentWindow)
is not working… is there any walk around here?

Env:
Appium 1.4.13
IOS8.3 simulator
Laungauge : java

Hi,

I had the same issue. Switching of tabs doesn’t happens. I searched a lot on forums but no answer.
I implemented a work around- I click on the coordinates which will bring the next tab on the top.
You can make this dynamic by getting the width of your device and then divide the width by number of tabs you are expecting.(apply some logic to play with coordintes) and for y - I used hardcoding. This strategy worked. You still need to do context switching. It happens internally but you have to bring that tab by the workaround to the top.

Below worked for me on ARC ( latest version along with Appium server )

tested with Android device + Chrome Browser

@se.window_handles
@se.switch_to.window("CDwindow-1")

P.S.
I hope this will help another poor sole working alone in a startup looking for ray of light in the end of tunnel :wink:

@VikramVI
Hi Vikram,

I tried the above solution shared by you, however I am getting error: Method has not yet been implemented.

I have updated the appium client files as well as selenium client files to the latest but still I am getting the same error.

I have restarted the Eclipse and appium after adding the jar files.

Below is my source code and please help to resolve this issue:

public class Browse {
AndroidDriver dr;
Dimension size;

@BeforeTest
public void loadsettings() throws MalformedURLException
{
	
	DesiredCapabilities cap = new DesiredCapabilities();
	cap.setCapability(MobileCapabilityType.PLATFORM_NAME,"Android");
	cap.setCapability(MobileCapabilityType.PLATFORM_VERSION, "7.0");
	cap.setCapability(MobileCapabilityType.DEVICE_NAME, "MOTO C Plus");
	cap.setCapability("appPackage", "com.motorola.launcher3");
	cap.setCapability("appActivity", "com.android.launcher3.GoogleNowPanel");
	dr = new AndroidDriver (new URL("http://127.0.0.1:4723/wd/hub"), cap );
}

@Test (priority=1)
public void run() throws InterruptedException
{
	
	
	size=dr.manage().window().getSize();
	System.out.println(size);
	
//to find the start point of the screen
int starty= (int)(size.height * 0.80);

//to find the end point of the screen
int endy= (int)(size.height * 0.10);
int startx = size.width / 2;
	int endx=0;
TouchAction action = new TouchAction((MobileDriver)dr);
WebElement e1= (WebElement)dr.findElement(By.id("all_apps_handle"));
action.longPress(e1).moveTo(startx, endy).release().perform();
}

@Test (priority=2)
public void browsepage() throws InterruptedException 
{

	WebDriverWait wait = new WebDriverWait(dr, 500);
dr.findElementByAccessibilityId("Chrome").click();
wait.until(ExpectedConditions.elementToBeClickable(By.id("com.android.chrome:id/url_bar"))).sendKeys("https://amazon.in");
dr.pressKeyCode(AndroidKeyCode.KEYCODE_NUMPAD_ENTER );

//Store current window handle
String winHandleBefore = dr.getWindowHandle();


TouchAction action = new TouchAction((MobileDriver)dr);
size=dr.manage().window().getSize();
int starty= (int)(size.height * 0.80);
int endy= (int)(size.height * 0.10);
int startx = size.width / 2;
int endx=0;

//TouchAction action = new TouchAction((MobileDriver)dr);
    WebElement e2= (WebElement)dr.findElementByClassName("android.view.View");
	action.press(e2).moveTo(startx, endy).release().perform();
	Thread.sleep(3000);
	action.press(e2).moveTo(endy, starty).release().perform();
	
	wait.until(ExpectedConditions.elementToBeClickable(By.id("com.android.chrome:id/tab_switcher_button"))).click();
	wait.until(ExpectedConditions.elementToBeClickable(By.id("com.android.chrome:id/new_tab_button"))).click();
	wait.until(ExpectedConditions.elementToBeClickable(By.id("com.android.chrome:id/search_box_text"))).sendKeys("yahoo.com");
	dr.pressKeyCode(AndroidKeyCode.ENTER);
	
	for(String winHandle : dr.getWindowHandles()){
	    dr.switchTo().window(winHandle);
	}
	
	dr.switchTo().window(winHandleBefore);
}

}

Thank you in advance.

@VikramVI
waiting for your reply.

Please reply.

Thank you.

This is what I tried and it appeared to have worked when switching Safari tabs with Appium 1.18.1 with Groovy. Java implementation shouldn’t be much different.

Note that I did not add following desired capabilities. Adding them broke this test for me.

capability.setCapability("safariAllowPopups", true)
capability.setCapability(IOSMobileCapabilityType.AUTO_ACCEPT_ALERTS, true)

Below is my implemenation. All sleep methods are using times in ms. These sleeps are very important. Clicking on Allow button to accept the permissions alerts takes time, little more than a minute but does work.

public void switchToNewTab() {
   clickElementByXpath(Xpath of the link that opens new tab) // This is just a wrapper method to find element and click by xpath. You can have your method to click the link. This displays a permissions alert message with Block and Allow buttons on it. Clicking on Allow opens the new tab.

   logger.info("Clicked on the link to open new tab")
   acceptAlert() // This method is to click on Allow button the permissions alert. Implimenation is below.
   sleep(3000) 
   Set<String> contextView = driver.getContextHandles()
   sleep(3000) 
   ArrayList<String> al = new ArrayList<String>(contextView) // This will get a list of 3 context views. One native where alert is present and two webviews for two tabs.
   sleep(2000)
   driver.context(al.get(2)) // This switches the focus to the newly opened tab.
   logger.info("Page title: " + driver.getTitle())
   // You can write more logic here to find what you are looking for your test.
  
  driver.close() // Close the newly opened tab. This has been a little inconsistent for me. It wouldn't always close. Perhaps you can try with adding some wait around it.

}

Implementation of acceptAlert() method.

private void acceptAlert() {
     swithContextTo("NATIVE") // Change the context to native to interact with the alert prompt.
     try {
          String alertText = driver.switchTo.alert().getText()
          logger.info(alertText)
          clickElementByIOSPredicateString("type=='XCUIElementTypeButton' AND name=='Allow'")
          // This is a wrapper method around findElement by predicate string)
          logger.info("Clicked on Allow button on permission alert.")
       } catch(Exception e) {
           e.printStackTrace()
      }
      swithContextTo("WEBVIEW")  // Don't forget to change the context back to Webview to interact with new browser tab.
}