How to get text from alert?

Requirement: To get the message from the alert i.e. “Invalid username or password.”

This is the webview in my mobile application and I am trying to access the text using webdriverio but I am facing challenges to achieve it.

I tried:

const alertError = await browser.$(.alert-error);
console.log(alertError);

but this is giving me error:

[0-1] 2022-06-14T08:42:21.250Z INFO webdriver: COMMAND findElement(“css selector”, “.alert-error”)
[0-1] 2022-06-14T08:42:21.250Z INFO webdriver: [POST] http://localhost:4723/session/81fed723-acd7-4d28-97bd-e2caed0009e5/element
[0-1] 2022-06-14T08:42:21.250Z INFO webdriver: DATA { using: ‘css selector’, value: ‘.alert-error’ }
[0-1] 2022-06-14T08:42:21.590Z INFO webdriver: RESULT {
[0-1] error: ‘no such element’,
[0-1] message: ‘An element could not be located on the page using the given search parameters.’,
[0-1] stacktrace: ‘NoSuchElementError: An element could not be located on the page using the given search parameters.\n’ +
[0-1] ’ at AndroidUiautomator2Driver.findElOrEls (/Users/harsha.sharmagelato.com/Dev/work/repos/gelato-api-mobile/integration-tests/node_modules/appium/node_modules/appium-android-driver/lib/commands/find.js:75:11)\n’ +
[0-1] ’ at processTicksAndRejections (internal/process/task_queues.js:95:5)\n’ +
[0-1] ’ at AndroidUiautomator2Driver.findElOrElsWithProcessing (/Users/harsha.sharmagelato.com/Dev/work/repos/gelato-api-mobile/integration-tests/node_modules/appium/node_modules/appium-base-driver/lib/basedriver/commands/find.js:33:12)\n’ +
[0-1] ’ at AndroidUiautomator2Driver.findElement (/Users/harsha.sharmagelato.com/Dev/work/repos/gelato-api-mobile/integration-tests/node_modules/appium/node_modules/appium-base-driver/lib/basedriver/commands/find.js:53:10)’
[0-1] }
[0-1] Element {
[0-1] sessionId: ‘81fed723-acd7-4d28-97bd-e2caed0009e5’,
[0-1] error: {
[0-1] error: ‘no such element’,
[0-1] message: ‘An element could not be located on the page using the given search parameters.’,
[0-1] stacktrace: ‘NoSuchElementError: An element could not be located on the page using the given search parameters.\n’ +
[0-1] ’ at AndroidUiautomator2Driver.findElOrEls (/Users/harsha.sharmagelato.com/Dev/work/repos/gelato-api-mobile/integration-tests/node_modules/appium/node_modules/appium-android-driver/lib/commands/find.js:75:11)\n’ +
[0-1] ’ at processTicksAndRejections (internal/process/task_queues.js:95:5)\n’ +
[0-1] ’ at AndroidUiautomator2Driver.findElOrElsWithProcessing (/Users/harsha.sharmagelato.com/Dev/work/repos/gelato-api-mobile/integration-tests/node_modules/appium/node_modules/appium-base-driver/lib/basedriver/commands/find.js:33:12)\n’ +
[0-1] ’ at AndroidUiautomator2Driver.findElement (/Users/harsha.sharmagelato.com/Dev/work/repos/gelato-api-mobile/integration-tests/node_modules/appium/node_modules/appium-base-driver/lib/basedriver/commands/find.js:53:10)’
[0-1] },
[0-1] selector: ‘.alert-error’,
[0-1] parent: Browser {
[0-1] sessionId: ‘81fed723-acd7-4d28-97bd-e2caed0009e5’,
[0-1] capabilities: {
[0-1] platform: ‘LINUX’,
[0-1] webStorageEnabled: false,
[0-1] takesScreenshot: true,
[0-1] javascriptEnabled: true,
[0-1] databaseEnabled: false,
[0-1] networkConnectionEnabled: true,
[0-1] locationContextEnabled: false,
[0-1] warnings: {},
[0-1] desired: [Object],
[0-1] platformName: ‘Android’,
[0-1] noReset: false,
[0-1] fullReset: false,
[0-1] automationName: ‘uiautomator2’,
[0-1] deviceName: ‘emulator-5554’,
[0-1] platformVersion: ‘11’,
[0-1] app: ‘…/build/app/outputs/flutter-apk/app-stage-release.apk’,
[0-1] appWaitDuration: 20000,
[0-1] newCommandTimeout: 12000,
[0-1] webviewConnectTimeout: 20000,
[0-1] fullContextList: false,
[0-1] autoAcceptAlerts: true,
[0-1] chromedriverExecutable: ‘./node_modules/chromedriver/lib/chromedriver/chromedriver’,
[0-1] chromeOptions: [Object],
[0-1] deviceUDID: ‘emulator-5554’,
[0-1] appPackage: ‘com.gelato.api.stage’,
[0-1] deviceApiLevel: 30,
[0-1] deviceScreenSize: ‘1080x2340’,
[0-1] deviceScreenDensity: 440,
[0-1] deviceModel: ‘sdk_gphone_arm64’,
[0-1] deviceManufacturer: ‘Google’,
[0-1] pixelRatio: 2.75,
[0-1] statBarHeight: 66,
[0-1] viewportRect: [Object]
[0-1] },
[0-1] addCommand: [Function (anonymous)],
[0-1] overwriteCommand: [Function (anonymous)],
[0-1] addLocatorStrategy: [Function (anonymous)],
[0-1] config: {
[0-1] specs: [Array],
[0-1] suites: {},
[0-1] exclude: ,
[0-1] outputDir: undefined,
[0-1] logLevel: ‘trace’,
[0-1] logLevels: {},
[0-1] excludeDriverLogs: ,
[0-1] bail: 0,
[0-1] waitforInterval: 500,
[0-1] waitforTimeout: 10000,
[0-1] framework: ‘cucumber’,
[0-1] reporters: [Array],
[0-1] services: [Array],
[0-1] maxInstances: 10,
[0-1] maxInstancesPerCapability: 100,
[0-1] filesToWatch: ,
[0-1] connectionRetryTimeout: 500000,
[0-1] connectionRetryCount: 3,
[0-1] execArgv: ,
[0-1] runnerEnv: {},
[0-1] runner: ‘local’,
[0-1] specFileRetries: 0,
[0-1] specFileRetriesDelay: 0,
[0-1] specFileRetriesDeferred: false,
[0-1] reporterSyncInterval: 100,
[0-1] reporterSyncTimeout: 5000,
[0-1] cucumberFeaturesWithLineNumbers: ,
[0-1] autoCompileOpts: [Object],
[0-1] mochaOpts: [Object],
[0-1] jasmineOpts: [Object],
[0-1] cucumberOpts: [Object],
[0-1] onPrepare: ,
[0-1] onWorkerStart: ,
[0-1] onWorkerEnd: ,
[0-1] before: ,
[0-1] beforeSession: ,
[0-1] beforeSuite: ,
[0-1] beforeHook: ,
[0-1] beforeTest: ,
[0-1] beforeCommand: ,
[0-1] afterCommand: ,
[0-1] afterTest: ,
[0-1] afterHook: ,
[0-1] afterSuite: ,
[0-1] afterSession: ,
[0-1] after: [Array],
[0-1] onComplete: [Array],
[0-1] onReload: ,
[0-1] beforeFeature: ,
[0-1] beforeScenario: ,
[0-1] beforeStep: ,
[0-1] afterStep: [Array],
[0-1] afterScenario: ,
[0-1] afterFeature: ,
[0-1] baseUrl: ‘http://localhost’,
[0-1] appium: [Object],
[0-1] port: 4723,
[0-1] path: ‘/wd/hub’,
[0-1] _: [Array],
[0-1] ‘$0’: ‘/Users/harsha.sharmagelato.com/Dev/work/repos/gelato-api-mobile/integration-tests/node_modules/.bin/wdio’,
[0-1] ignoredWorkerServices:
[0-1] }
[0-1] },
[0-1] emit: [Function: bound ],
[0-1] isReactElement: false,
[0-1] addCommand: [Function (anonymous)],
[0-1] overwriteCommand: [Function (anonymous)]
[0-1] }

I don’t understand what I am missing at my end.
Any inputs will be appreciated. Thank you :slight_smile:

I’m assuming this is on Android?
Reading the text out of an alert is a recipe for disaster. If the alert is raised by a different context, you will need to switch to get it, (although that looks like it’s not a problem in this case) but if the alert disappears before you get to read it (a very common problem) you will have a very flakey test case. Only do this for persistent notifications which you want to interact with, otherwise just do not test alerts if you can help it.

Having a test case hinge on a fleeting event can be easily avoided as a source of flakiness by having the developer provide a hook into the app logging or other way, to allow the tester to verify app state. Normally you need to be testing for “outcomes”, try to avoid testing alerts, it’s not a brilliant way to test. Perhaps you are jsut wanting to check that the password was incorrect. When this happens, the login will fail, so that’s the outcome you are interested in. Thing like UI furniture are not a great candidate for automation check because on-screen keyboards often obscure them too. Hope you can find a way to re-design your test case.

Thankyou for taking on this and giving the feedback.
I am reporting this issue for both Android and IOS device.
It seems to me that checking of alert is not a good option instead of that we should check whether the screen after login appeared or not? Am I right?

In my case contexts available before and after alert is same:

[0-1] 2022-06-14 13:31:57.732 DEBUG [src/stepDefinitions/login.ts:74 World.<anonymous>] Context available after alert:{}, NATIVE_APP,WEBVIEW_chrome

Yeah. I mean you can try and make sure your test can grab the alert, it’s just not a great way to test. Most users do not really read the actual notifications. They are not designed to be easy to test.

We were able to do it in our Android app. It’s not a bug in the appium tool (its jsut a wrapper) or in the app driver or app-framework at all, it’s just that each webdriver driver is different internally. I see you are also using the Android Uiautomator2 driver :slight_smile: , but your app might be browser, we have a native app. And I’m only opening the “persistent notification”, yours is not persistent. I have asked the devs to add a special remote testing hook into our app, by building it in a special test profile with this hook in which lets me test read some data from the app via a back-channel web api. It’s all about designing the UI so that it is easy to test, and then designing tests that are easy to maintain. good luck going forwards