Open a URL using Appium in Mobile Webview

Sandeep Dinesh
3 min readSep 3, 2021

One of the advantages of having a Mobile app built as a package of an embedded website is that we can treat individual pages as web pages opened on a browser’s window. Session management will be done by the underlying mobile platform just like how a browser would do

Let’s say we want to navigate to a Home page, open the Settings page for e.g, or as part of a strategy to take the mobile to a steady-state location, usually a Login Screen or HomeScreen.

Usually, we write code in @ Before* and @ After* blocks with a loop of arduous click streams, usually the Back button, until we reach the targeted page.

I am sharing here how to get this done fastly for such Mobile Apps, and the good news is that this works on both Android and iOS for them!

On to the Code/ TLDR


await I.executeScript(async function() {
await window.open('<Relative Path URL>', '_self');
}, <TIMEOUT>);
/*The Relative Path URL should ALWAYS start with a '/'TIMEOUT is the time post which Appium will quit waiting for script executionfor e.g.If your website has a relative path /home to go to the Home Pageawait I.executeScript(async function() {
await window.open('/home', '_self');
}, 60000);
orIf your website has a relative path /profile to go to the Profile Page with viewerMode param as 1await I.executeScript(async function() {
await window.open('/profile?viewerMode=1', '_self');
}, 60000);
*/

This is a codeceptJS example, modify according to the API specifications of Appium’s executeScript API as per your programming language and underlying test framework

Explanation

  1. Onto the WebView of the mobile App, Appium will inject the javascript command for doing a page refresh to the relative path we are passing.
  2. The second parameter in window.open javascript API can be ‘_self’ (which opens URL in the same Tab) , ‘_parent’ (which opens URL in the parent frame), or ‘_top’ (which opens URL in the topmost frame). In the course of my usage on my app, it doesn’t matter if any of these value is passed, and in most cases ‘_self’ should do what you need to. Still you can explore other parameters depending upon your particular app design

Limitations

Certainly, there are certain limitations to this approach let me briefly explain them, and tips to circumvent a few.

  1. We cannot navigate outside of the mobile app’s origin URL. Let’s see we try to pass a fully qualified URL, the underlying security system of Android and iOS would kick in and prevent a “hijacking” of a third party website into the Mobile’s webview. (so strict that even the URL on which the app is hosted itself is not accepted!)
  2. If you don’t pass the second parameter to the script, which is not mandatory for window.open API, In Android devices, the underlying webView will pass the request to Chrome App (which we don’t want) and in iOS, safari just ignores the request. So, ensure the second parameter is passed!
  3. There are some circumstances where the URL where we want to go is dynamic or there is a case for understanding where we are in terms of the relative path of the website. In such scenarios, this snippet would be handy.
const location = await I.executeScript(async function() {
return await window.location;
}, <TIMEOUT>);

/*
Location object contains the following data for e.g.{
ancestorOrigins: [],
assign: {},
hash: '',
host: 'foo.com',
hostname: 'foo.com',
href: 'https://idp.foo.com/login?redirect_uri=https://client.foo.com/home&device=mobileapp',
origin: 'https://idp.foo.com',
pathname: '/login',
port: '',
protocol: 'https:',
reload: {},
replace: {},
search: '?redirect_uri=https://client.foo.com/home&device=mobileapp',
toString: {}
}
What we are intresested is the pathname param*/await I.executeScript(async function() {
await window.open(location['pathname'], '_self');
}, <TIMEOUT>);

Happy Test Automation!

--

--