Skip to content

Commit

Permalink
feat: Return default window handle in native context (#966)
Browse files Browse the repository at this point in the history
  • Loading branch information
mykola-mokhnach authored Nov 13, 2024
1 parent 07ec95d commit 4426dd2
Show file tree
Hide file tree
Showing 2 changed files with 72 additions and 16 deletions.
82 changes: 66 additions & 16 deletions lib/commands/context/exports.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/* eslint-disable require-await */
import {util} from '@appium/support';
import Chromedriver from 'appium-chromedriver';
import {errors} from 'appium/driver';
import {errors, PROTOCOLS} from 'appium/driver';
import _ from 'lodash';
import {
CHROMIUM_WIN,
Expand All @@ -18,8 +18,11 @@ import {
} from './helpers';
import {APP_STATE} from '../app-management';

// https://github.com/appium/appium/issues/20710
const DEFAULT_NATIVE_WINDOW_HANDLE = '1';

/**
* @this {import('../../driver').AndroidDriver}
* @this {AndroidDriver}
* @returns {Promise<string>}
*/
export async function getCurrentContext() {
Expand All @@ -29,7 +32,7 @@ export async function getCurrentContext() {
}

/**
* @this {import('../../driver').AndroidDriver}
* @this {AndroidDriver}
* @returns {Promise<string[]>}
*/
export async function getContexts() {
Expand All @@ -38,7 +41,7 @@ export async function getContexts() {
}

/**
* @this {import('../../driver').AndroidDriver}
* @this {AndroidDriver}
* @param {string?} name
* @returns {Promise<void>}
*/
Expand Down Expand Up @@ -66,7 +69,7 @@ export async function setContext(name) {
}

/**
* @this {import('../../driver').AndroidDriver}
* @this {AndroidDriver}
* @param {any} [opts={}]
* @returns {Promise<import('../types').WebviewsMapping[]>}
*/
Expand All @@ -82,7 +85,7 @@ export async function mobileGetContexts(opts = {}) {
}

/**
* @this {import('../../driver').AndroidDriver}
* @this {AndroidDriver}
* @param {import('../types').WebviewsMapping[]} webviewsMapping
* @returns {string[]}
*/
Expand All @@ -95,7 +98,7 @@ export function assignContexts(webviewsMapping) {
}

/**
* @this {import('../../driver').AndroidDriver}
* @this {AndroidDriver}
* @param {string} name
* @param {import('../types').WebviewsMapping[]} webviewsMapping
* @returns {Promise<void>}
Expand Down Expand Up @@ -123,33 +126,79 @@ export async function switchContext(name, webviewsMapping) {
}

/**
* @this {import('../../driver').AndroidDriver}
* @this {AndroidDriver}
* @returns {string}
*/
export function defaultContextName() {
return NATIVE_WIN;
}

/**
* @this {import('../../driver').AndroidDriver}
* @this {AndroidDriver}
* @returns {string}
*/
export function defaultWebviewName() {
return WEBVIEW_BASE + (this.opts.autoWebviewName || this.opts.appPackage);
}

/**
* @this {import('../../driver').AndroidDriver}
* @this {AndroidDriver}
* @returns {boolean}
*/
export function isWebContext() {
return this.curContext !== null && this.curContext !== NATIVE_WIN;
}

/**
* @this {AndroidDriver}
* @returns {Promise<string>}
*/
export async function getWindowHandle() {
if (!this.isWebContext()) {
return DEFAULT_NATIVE_WINDOW_HANDLE;
}

const chromedriver = /** @type {Chromedriver} */ (this.chromedriver);
const isJwp = chromedriver.jwproxy.downstreamProtocol === PROTOCOLS.MJSONWP;
const endpoint = isJwp ? '/window_handle' : '/window/handle';
return /** @type {string} */ (await chromedriver.jwproxy.command(endpoint, 'GET'));
}

/**
* @this {AndroidDriver}
* @returns {Promise<string[]>}
*/
export async function getWindowHandles() {
if (!this.isWebContext()) {
return [DEFAULT_NATIVE_WINDOW_HANDLE];
}

const chromedriver = /** @type {Chromedriver} */ (this.chromedriver);
const isJwp = chromedriver.jwproxy.downstreamProtocol === PROTOCOLS.MJSONWP;
const endpoint = isJwp ? '/window_handles' : '/window/handles';
return /** @type {string[]} */ (await chromedriver.jwproxy.command(endpoint, 'GET'));
}

/**
* @this {AndroidDriver}
* @param {string} handle
* @returns {Promise<void>}
*/
export async function setWindow(handle) {
if (!this.isWebContext()) {
return;
}

const chromedriver = /** @type {Chromedriver} */ (this.chromedriver);
const isJwp = chromedriver.jwproxy.downstreamProtocol === PROTOCOLS.MJSONWP;
const paramName = isJwp ? 'name' : 'handle';
await chromedriver.jwproxy.command('/window', 'POST', {[paramName]: handle});
}

/**
* Turn on proxying to an existing Chromedriver session or a new one
*
* @this {import('../../driver').AndroidDriver}
* @this {AndroidDriver}
* @param {string} context
* @param {import('../types').WebviewsMapping[]} webviewsMapping
* @returns {Promise<void>}
Expand Down Expand Up @@ -255,7 +304,7 @@ export async function startChromedriverProxy(context, webviewsMapping) {
/**
* Stop proxying to any Chromedriver
*
* @this {import('../../driver').AndroidDriver}
* @this {AndroidDriver}
* @returns {void}
*/
export function suspendChromedriverProxy() {
Expand All @@ -268,7 +317,7 @@ export function suspendChromedriverProxy() {
/**
* Handle an out-of-band Chromedriver stop event
*
* @this {import('../../driver').AndroidDriver}
* @this {AndroidDriver}
* @param {string} context
* @returns {Promise<void>}
*/
Expand All @@ -293,7 +342,7 @@ export async function onChromedriverStop(context) {
* Intentionally stop all the chromedrivers currently active, and ignore
* their exit events
*
* @this {import('../../driver').AndroidDriver}
* @this {AndroidDriver}
* @returns {Promise<void>}
*/
export async function stopChromedriverProxies() {
Expand All @@ -313,7 +362,7 @@ export async function stopChromedriverProxies() {
}

/**
* @this {import('../../driver').AndroidDriver}
* @this {AndroidDriver}
* @param {string} viewName
* @returns {boolean}
*/
Expand All @@ -322,7 +371,7 @@ export function isChromedriverContext(viewName) {
}

/**
* @this {import('../../driver').AndroidDriver}
* @this {AndroidDriver}
* @returns {Promise<void>}
*/
export async function startChromeSession() {
Expand Down Expand Up @@ -376,4 +425,5 @@ export async function startChromeSession() {

/**
* @typedef {import('appium-adb').ADB} ADB
* @typedef {import('../../driver').AndroidDriver} AndroidDriver
*/
6 changes: 6 additions & 0 deletions lib/driver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,9 @@ import {
suspendChromedriverProxy,
startChromeSession,
mobileGetContexts,
getWindowHandle,
getWindowHandles,
setWindow,
} from './commands/context/exports';
import {
getDeviceInfoFromCaps,
Expand Down Expand Up @@ -365,6 +368,9 @@ class AndroidDriver
isWebContext = isWebContext;
mobileGetContexts = mobileGetContexts;
setContext = setContext as any as (this: AndroidDriver, name?: string) => Promise<void>;
setWindow = setWindow;
getWindowHandle = getWindowHandle;
getWindowHandles = getWindowHandles;

getDeviceInfoFromCaps = getDeviceInfoFromCaps;
createADB = createADB;
Expand Down

0 comments on commit 4426dd2

Please sign in to comment.