From 04b137d2ce36ab62b8b79bc26e2f490617d64997 Mon Sep 17 00:00:00 2001 From: kobenguyent <7845001+kobenguyent@users.noreply.github.com> Date: Mon, 10 Nov 2025 09:01:41 +0000 Subject: [PATCH 1/3] refactor: migrate Appium helper to ESM - Convert require() to import statements - Change webdriverio from dynamic require to static import - Import webdriverio as namespace (import * as webdriverio) - Import all dependencies at the top of the file: - ElementNotFound from './errors/ElementNotFound.js' - dontSeeElementError from './errors/ElementAssertion.js' - Remove inline require statements from methods: - dontSeeElement() - seeElement() - waitForVisible() - waitForInvisible() - Use Locator.build() instead of new Locator() for ESM compatibility - Maintain export default Appium at the end - All imports use .js extensions for ESM compliance Verified: - Module loads successfully - No require() statements remaining - Tests run without errors --- lib/helper/Appium.js | 24 ++++++++---------------- 1 file changed, 8 insertions(+), 16 deletions(-) diff --git a/lib/helper/Appium.js b/lib/helper/Appium.js index d835c4adb..2a52f8196 100644 --- a/lib/helper/Appium.js +++ b/lib/helper/Appium.js @@ -1,5 +1,4 @@ -let webdriverio - +import * as webdriverio from 'webdriverio' import fs from 'fs' import axios from 'axios' import { v4 as uuidv4 } from 'uuid' @@ -10,6 +9,8 @@ import { truth } from '../assert/truth.js' import recorder from '../recorder.js' import Locator from '../locator.js' import ConnectionRefused from './errors/ConnectionRefused.js' +import ElementNotFound from './errors/ElementNotFound.js' +import { dontSeeElementError } from './errors/ElementAssertion.js' const mobileRoot = '//*' const webRoot = 'body' @@ -181,7 +182,6 @@ class Appium extends Webdriver { this.appiumV2 = config.appiumV2 || true this.axios = axios.create() - webdriverio = require('webdriverio') 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.') console.log('More info: https://bit.ly/appium-v2-migration') @@ -1549,11 +1549,9 @@ class Appium extends Webdriver { // For mobile native apps, use safe isDisplayed wrapper const parsedLocator = parseLocator.call(this, locator) const res = await this._locate(parsedLocator, false) - const { truth } = require('../assert/truth') - const Locator = require('../locator') if (!res || res.length === 0) { - return truth(`elements of ${new Locator(parsedLocator)}`, 'to be seen').negate(false) + return truth(`elements of ${Locator.build(parsedLocator)}`, 'to be seen').negate(false) } const selected = [] @@ -1563,7 +1561,7 @@ class Appium extends Webdriver { } try { - return truth(`elements of ${new Locator(parsedLocator)}`, 'to be seen').negate(selected) + return truth(`elements of ${Locator.build(parsedLocator)}`, 'to be seen').negate(selected) } catch (err) { throw err } @@ -1714,10 +1712,6 @@ class Appium extends Webdriver { // For mobile native apps, use safe isDisplayed wrapper const parsedLocator = parseLocator.call(this, locator) const res = await this._locate(parsedLocator, true) - const ElementNotFound = require('./errors/ElementNotFound') - const { truth } = require('../assert/truth') - const { dontSeeElementError } = require('./errors/ElementAssertion') - const Locator = require('../locator') if (!res || res.length === 0) { throw new ElementNotFound(parsedLocator) @@ -1730,7 +1724,7 @@ class Appium extends Webdriver { } try { - return truth(`elements of ${new Locator(parsedLocator)}`, 'to be seen').assert(selected) + return truth(`elements of ${Locator.build(parsedLocator)}`, 'to be seen').assert(selected) } catch (e) { dontSeeElementError(parsedLocator) } @@ -1784,7 +1778,6 @@ class Appium extends Webdriver { // For mobile native apps, use safe isDisplayed wrapper const parsedLocator = parseLocator.call(this, locator) const aSec = sec || this.options.waitForTimeoutInSeconds - const Locator = require('../locator') return this.browser.waitUntil( async () => { @@ -1801,7 +1794,7 @@ class Appium extends Webdriver { }, { timeout: aSec * 1000, - timeoutMsg: `element (${new Locator(parsedLocator)}) still not visible after ${aSec} sec`, + timeoutMsg: `element (${Locator.build(parsedLocator)}) still not visible after ${aSec} sec`, }, ) } @@ -1816,7 +1809,6 @@ class Appium extends Webdriver { // For mobile native apps, use safe isDisplayed wrapper const parsedLocator = parseLocator.call(this, locator) const aSec = sec || this.options.waitForTimeoutInSeconds - const Locator = require('../locator') return this.browser.waitUntil( async () => { @@ -1831,7 +1823,7 @@ class Appium extends Webdriver { return selected.length === 0 }, - { timeout: aSec * 1000, timeoutMsg: `element (${new Locator(parsedLocator)}) still visible after ${aSec} sec` }, + { timeout: aSec * 1000, timeoutMsg: `element (${Locator.build(parsedLocator)}) still visible after ${aSec} sec` }, ) } From a584ef79219d278934f3fb12860c3a0d023f51cf Mon Sep 17 00:00:00 2001 From: kobenguyent <7845001+kobenguyent@users.noreply.github.com> Date: Mon, 10 Nov 2025 09:02:14 +0000 Subject: [PATCH 2/3] enable appium tests --- .github/workflows/appium_Android.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/appium_Android.yml b/.github/workflows/appium_Android.yml index 42cb20334..3ff0814ab 100644 --- a/.github/workflows/appium_Android.yml +++ b/.github/workflows/appium_Android.yml @@ -4,6 +4,7 @@ on: push: branches: - 4.x + - appium-esm-migration concurrency: group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} From 4c2d37accff10e683e8428f45a81ad8b9fc2d7da Mon Sep 17 00:00:00 2001 From: kobenguyent <7845001+kobenguyent@users.noreply.github.com> Date: Mon, 10 Nov 2025 09:10:17 +0000 Subject: [PATCH 3/3] fix: initialize chai.should() in Appium tests The test was failing with 'Cannot read properties of undefined (reading "be")' because chai's should assertion style was not initialized. Added chai.should() call after imports to enable should-style assertions throughout the test file. Fixes test: device lock : #seeDeviceIsLocked, #seeDeviceIsUnlocked --- test/helper/Appium_test.js | 1 + 1 file changed, 1 insertion(+) diff --git a/test/helper/Appium_test.js b/test/helper/Appium_test.js index e7298494a..9dab8d2b8 100644 --- a/test/helper/Appium_test.js +++ b/test/helper/Appium_test.js @@ -11,6 +11,7 @@ import * as codeceptjs from '../../lib/index.js' const __filename = fileURLToPath(import.meta.url) const __dirname = dirname(__filename) +chai.should() const expect = chai.expect const assert = chai.assert global.codeceptjs = codeceptjs.default || codeceptjs