Don't click element on ios

Sorry again for the trouble(

You have already helped me unreal many times, but now I can’t understand what to do. A new mobile application project was given. But I encountered the problem that any element is not called.

@iOSXCUITFindBy(xpath = “//*[contains(@name, ‘Дале’)]”)
private val nextButton: SelenideElement? = null
nextButton?.click()

I also tried “tap”

appium returns success, the action will be completed successfully, but nothing actually happened on the screen.

<XCUIElementTypeButton type = “XCUIElementTypeButton” name = “Дале” label = “Дале” enabled = “true” visible = “true” accessible = “true” x = “339” y = “551” width = “75” height = “44” index = “0” />
<XCUIElementTypeStaticText type = “XCUIElementTypeStaticText” value = “Дале” name = “Дале” label = “Дале” enabled = “true” visible = “true” accessible = “false” x = “190” y = “808” width = “34” height = “20” index = “0” />

what could be?

@Aleksei hoping you can help me pls.

  1. never use xPath for iOS. is it slow as hell.
  2. name attribute is actully id
  3. before doing tap get element center and compare visually with element position you trying to tap. is it correct element found?
  4. better ask dev to put elements IDs or learn how to do it yourself :slight_smile: and make PR to iOS code.
  5. remember that looking for text like Далè or Далê or similar can be problem. In source code it can be NOT same as you see on screen. just FYI.
  6. better use:
    @iOSXCUITFindBy(id = "Дале")
    // or
    @iOSXCUITFindBy(iOSNsPredicate = "type == 'XCUIElementTypeButton' AND name == 'Дале'")
    // or
    @iOSXCUITFindBy(iOSClassChain = "**/XCUIElementTypeButton[`name == \"Дале\"`]")
  1. possibly we can make better search. need to see whole page source. you can share it with removing all private staff or in private message.

PS
8. check that NO more Дале text in page source found. possibly you just look for wrong element.

@Aleksei
Thanks a lot for the advice!

I always use iOSClassChain or accessibility, the example above is just that I have already tested everything that is on the element)

About “before doing tap get element center and compare visually with element position you trying to tap.” - unfortunately, I don’t quite understand (maybe I just haven’t seen/don’t know this) - how can I visually check where my autotest code clicks? if it is not clickable (always relied only on a real click)

and about 7-8:
Unfortunately, I do not have access to the application code, I received a ready-made application, indicating its bundleID and just writing autotests =(
Yes, and I have a problem not with a specific button, I have a problem with everything in this application.
That is, I can run it with a test by its bundleID, but already on the very first screen I don’t click on any element
Absolutely none
I have 3 buttons on the screen and one field for text. I can paste text using send or type but nothing else. All that I do not press - do not really press on the screen, but appium sends a response that it found an element on the screen and successfully clicked on it.

I open another application where I wrote the test exactly the same as I write here, the same computer, washing device, the same appium - and everything works there?!
I return to the first application - the type clicked again - but in fact it did not click. Why - I don’t understand…

You know screen size. Now you have tap point. So just check is it correct place.

Maybe share also code…

@Aleksei

test class:
package common.helpers

import com.codeborne.selenide.SelenideElement
import common.ApplicationManager
import constants.Constants
import io.appium.java_client.MobileElement
import io.appium.java_client.pagefactory.AndroidFindBy
import io.appium.java_client.pagefactory.iOSXCUITFindBy
import org.openqa.selenium.interactions.touch.TouchActions
import sсreens.Autorization
import java.lang.Thread.sleep

open class AuthHelper(manager: ApplicationManager) : ApplicationManager() {
var manager: ApplicationManager

init {
    this.manager = manager
}

@AndroidFindBy(id = "ua.com.abank:id/btnNext")
@iOSXCUITFindBy(xpath = "//*[contains(@name, 'Дале')]")
private val nextButton: MobileElement? = null

@iOSXCUITFindBy(xpath = "//*[contains(@name, 'Отменить')]")
private val authdScreen: SelenideElement? = null

@iOSXCUITFindBy(accessibility = "ic chat new")
private var fieldFour: SelenideElement? =

fun fullAuth(): Autorization {
    when (Constants.RunVariables.PLATFORM) {
        Constants.Platform.IOS -> {
          nextButton?.click()
           tap(fieldFour)
            fieldFour?.click()

sleep(3000)

            nextButton?.click()


        }
        Constants.Platform.AOS -> {
            manager.getScreen<Autorization>()
                .skipPermissions()
                .skipAllerScreen()
                .enterPhoneNumber()
                .setPassCode()
                .setOTPCodeAndroid()
        }
    }
    return manager.getScreen()
}

fun reAuth(): Autorization {
    when (Constants.RunVariables.PLATFORM) {
        Constants.Platform.IOS -> {
            manager.getScreen<Autorization>()
                .setPassCode()


        }
        Constants.Platform.AOS -> {
            manager.getScreen<Autorization>()
                .setPassCode()
        }
    }
    return manager.getScreen()
}

}

ApplicationManager:
package common

import com.codeborne.selenide.Selenide
import com.codeborne.selenide.SelenideElement
import com.codeborne.selenide.WebDriverRunner
import com.codeborne.selenide.appium.ScreenObject.screen
import com.google.common.collect.ImmutableMap
import common.helpers.DataReader.getValue
import constants.Constants
import io.appium.java_client.AppiumDriver
import io.appium.java_client.android.AndroidDriver
import io.appium.java_client.ios.IOSDriver
import io.appium.java_client.remote.AndroidMobileCapabilityType.*
import io.appium.java_client.remote.MobileCapabilityType.*
import org.openqa.selenium.interactions.touch.TouchActions
import org.openqa.selenium.remote.CapabilityType.PLATFORM_NAME
import org.openqa.selenium.remote.DesiredCapabilities
import java.io.File
import java.lang.reflect.Constructor
import java.lang.reflect.InvocationTargetException
import java.net.MalformedURLException
import java.net.URL
import java.util.concurrent.TimeUnit

open class ApplicationManager {

private var driver: AppiumDriver<*>? = null
private val clipboard = Selenide.clipboard()

@JvmName("getDriver1")
fun createDriver(): AppiumDriver<*> {
    var driver: AppiumDriver<*>? = null
    try {
        val url = URL("http://127.0.0.1:4723/wd/hub")
        return when (Constants.RunVariables.PLATFORM) {
            Constants.Platform.IOS -> {
                if (driver == null) {
                    driver = IOSDriver<SelenideElement>(url, iOSDesiredCapabilities)
                }
                driver
            }

            Constants.Platform.AOS -> {
                if (driver == null) {
                    driver = AndroidDriver<SelenideElement>(url, androidDesiredCapabilities)
                }
                driver.manage().timeouts().implicitlyWait(7, TimeUnit.SECONDS)
                driver
            }
        }
    } catch (e: MalformedURLException) {
        e.printStackTrace()
    }
    throw IllegalArgumentException("Cannot detect type of the Driver. Platform value: " + "name")
}

private val androidDesiredCapabilities: DesiredCapabilities
    get() {
        val appDir = File("src/test/kotlin/app")
        val app = File(appDir, "app-debug.apk")

        val desiredCapabilities = DesiredCapabilities()
        desiredCapabilities.setCapability(DEVICE_NAME, getValue("AOS_DEVICE_NAME"))
        desiredCapabilities.setCapability(UDID, getValue("AOS_UDID"))
        desiredCapabilities.setCapability(PLATFORM_NAME, "Android")
        desiredCapabilities.setCapability(PLATFORM_VERSION, getValue("AOS_PLATFORM_VERSION"))
        desiredCapabilities.setCapability(APP_PACKAGE, "*******")
        desiredCapabilities.setCapability(APP, app.getAbsolutePath())

// “appium:autoGrantPermissions”: true
desiredCapabilities.setCapability(NO_RESET, true)
desiredCapabilities.setCapability(“appium:autoGrantPermissions”, “true”)

        return desiredCapabilities
    }

private val iOSDesiredCapabilities: DesiredCapabilities
    get() {
        val desiredCapabilities = DesiredCapabilities()
        desiredCapabilities.setCapability(DEVICE_NAME, getValue("IOS_DEVICE_NAME"))
        desiredCapabilities.setCapability("automationName", "XCUITest")
        desiredCapabilities.setCapability(PLATFORM_VERSION, getValue("IOS_PLATFORM_VERSION"))
        desiredCapabilities.setCapability(PLATFORM_NAME, "iOS")
        desiredCapabilities.setCapability(UDID, getValue("IOS_UDID"))
        desiredCapabilities.setCapability("autoAcceptAlerts", true)
        desiredCapabilities.setCapability("bundleId", "**********")
        return desiredCapabilities
    }

fun getDriver(): AppiumDriver<*> {
    return WebDriverRunner.getWebDriver() as AppiumDriver<*>
}

inline fun <reified T> getHelper(): T {
    val clazz: Class<*>?
    val constructor: Constructor<*>?
    var `object`: Any? = null
    try {
        clazz = T::class.java
        constructor = clazz.getConstructor(ApplicationManager::class.java)
        `object` = constructor.newInstance(this)
    } catch (e: ClassNotFoundException) {
        e.printStackTrace()
    } catch (e: NoSuchMethodException) {
        e.printStackTrace()
    } catch (e: IllegalAccessException) {
        e.printStackTrace()
    } catch (e: InstantiationException) {
        e.printStackTrace()
    } catch (e: InvocationTargetException) {
        e.printStackTrace()
    }
    return `object` as T
}

inline fun <reified T> getScreen(): T {
    return screen(T::class.java)
}


fun setClipboardText(text: String) {
    clipboard.text = text
}

fun getClipboardText(): String {
    return clipboard.text

}

fun tap(text: SelenideElement?) {

    val action = TouchActions(driver)
    action.singleTap(text)
    action.perform()
}

}

My tree:

-ios class chain (docs) **/XCUIElementTypeButton[label == "Далее"]
-ios predicate string (docs) label == “Далее” AND name == “Далее” AND type == “XCUIElementTypeButton”
xpath //XCUIElementTypeButton[@name=“Далее”]
Attribute Value
elementId 2F000000-0000-0000-7B4D-000000000000
type XCUIElementTypeButton
name Далее
label Далее
enabled true
visible true
accessible true
x 24
y 790
width 366
height 56
index 4

try use tap instead of click. I use https://appium.io/docs/en/commands/interactions/actions/

[android]
Also may try https://github.com/appium/appium-uiautomator2-driver#platform-specific-extensions -> * mobile: clickGesture -> https://appium.io/docs/en/writing-running-appium/android/android-mobile-gestures/

[ios] has similar. find yourself :slight_smile:

@Aleksei
Much appreciated for your help!

Found a solution to my problem. But I had to rewrite the project a little =(
Let’s just say it didn’t follow the pattern.

used
fun getDriver(): AppiumDriver<> {
return WebDriverRunner.getWebDriver() as AppiumDriver<
>
}

and after elements processed as SelenideElement?

The solution was to use IOSDriver and AndroidDriver separately

and the element began to process as MobileElement

and everything worked)
now everything clicks