diff --git a/.github/workflows/appium_Android.yml b/.github/workflows/appium_Android.yml index 5c47b83fe..20c9e5efb 100644 --- a/.github/workflows/appium_Android.yml +++ b/.github/workflows/appium_Android.yml @@ -5,6 +5,9 @@ on: branches: - 4.x - appium-esm-migration + pull_request: + branches: + - 4.x concurrency: group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} diff --git a/lib/element/WebElement.js b/lib/element/WebElement.js index 79c8793f2..e646870f0 100644 --- a/lib/element/WebElement.js +++ b/lib/element/WebElement.js @@ -15,10 +15,13 @@ class WebElement { _detectHelperType(helper) { if (!helper) return 'unknown' - const className = helper.constructor.name - if (className === 'Playwright') return 'playwright' - if (className === 'WebDriver') return 'webdriver' - if (className === 'Puppeteer') return 'puppeteer' + let ctor = helper.constructor + while (ctor && ctor.name) { + if (ctor.name === 'Playwright') return 'playwright' + if (ctor.name === 'WebDriver') return 'webdriver' + if (ctor.name === 'Puppeteer') return 'puppeteer' + ctor = Object.getPrototypeOf(ctor) + } return 'unknown' } diff --git a/lib/helper/Appium.js b/lib/helper/Appium.js index d0908b67f..427c3e03e 100644 --- a/lib/helper/Appium.js +++ b/lib/helper/Appium.js @@ -179,13 +179,13 @@ class Appium extends Webdriver { super(config) this.isRunning = false - this.appiumV2 = config.appiumV2 || true + this.appiumV2 = config.appiumV2 !== false this.axios = axios.create() - if (!config.appiumV2) { - console.log('The Appium core team does not maintain Appium 1.x anymore since the 1st of January 2022. Appium 2.x is used by default.') + if (this.appiumV2 === false) { + console.log('Appium 1.x is no longer maintained by the Appium team (since 2022-01-01).') console.log('More info: https://bit.ly/appium-v2-migration') - console.log('This Appium 1.x support will be removed in next major release.') + console.log('Appium 1.x support will be removed in the next major CodeceptJS release.') } } @@ -220,6 +220,9 @@ class Appium extends Webdriver { deprecationWarnings: false, restart: true, manualStart: false, + // Mobile emulator/device cold starts (esp. on cloud grids like Sauce Labs) + // routinely exceed webdriverio's 2-minute default. Bump to 5 min. + connectionRetryTimeout: 300000, // ms timeouts: { script: 0, // ms }, @@ -331,6 +334,24 @@ class Appium extends Webdriver { } this.$$ = this.browser.$$.bind(this.browser) + // wdio v9 implements `element.isDisplayed()` for non-mobile contexts by + // injecting a JS visibility check via POST /execute/sync. Appium's native + // context cannot execute JS, so each call logs an ugly + // "Method is not implemented" ERROR before the existing catch swallows it. + // Short-circuit isDisplayed to `true` while in native context so the + // request is never issued (matches existing _isDisplayedSafe semantics). + const helper = this + if (typeof this.browser.overwriteCommand === 'function') { + this.browser.overwriteCommand( + 'isDisplayed', + async function (origFn, ...args) { + if (helper.isWeb) return origFn.call(this, ...args) + return true + }, + true, + ) + } + this.isRunning = true if (this.options.timeouts && this.isWeb) { await this.defineTimeout(this.options.timeouts) diff --git a/lib/helper/WebDriver.js b/lib/helper/WebDriver.js index cf22e8639..62c0b4dc2 100644 --- a/lib/helper/WebDriver.js +++ b/lib/helper/WebDriver.js @@ -1264,7 +1264,7 @@ class WebDriver extends Helper { const elem = selectElement(res, field, this) highlightActiveElement.call(this, elem) - if (await fillRichEditor(this, elem, value)) { + if (this.isWeb !== false && await fillRichEditor(this, elem, value)) { return } diff --git a/test/helper/Appium_test.js b/test/helper/Appium_test.js index ce3942346..6208b7988 100644 --- a/test/helper/Appium_test.js +++ b/test/helper/Appium_test.js @@ -21,7 +21,7 @@ const apk_path = 'storage:filename=selendroid-test-app-0.17.0.apk' const smallWait = 3 describe('Appium', function () { - // this.retries(1); + this.retries(1) this.timeout(0) before(async () => { diff --git a/test/unit/WebElement_test.js b/test/unit/WebElement_test.js index 3da5a9570..2c200c521 100644 --- a/test/unit/WebElement_test.js +++ b/test/unit/WebElement_test.js @@ -36,6 +36,22 @@ describe('WebElement', () => { expect(webElement.helperType).to.equal('unknown') }) + + it('should detect Appium as webdriver via prototype chain', () => { + class WebDriver {} + class Appium extends WebDriver {} + const webElement = new WebElement({}, new Appium()) + + expect(webElement.helperType).to.equal('webdriver') + }) + + it('should detect subclasses of Playwright as playwright', () => { + class Playwright {} + class CustomPlaywright extends Playwright {} + const webElement = new WebElement({}, new CustomPlaywright()) + + expect(webElement.helperType).to.equal('playwright') + }) }) describe('getText()', () => {