javaswiftuiuikitappiumaccessibility-inspector

SwiftUI accessibility ID not able to be accesse by automated testing framework


In the app I'm working on, I have a SwiftUI View embedded in a UIKit Storyboard. The SwiftUI View holds a menu with a list of payment tools, and the ForEach loop looks like this:

ForEach(self.paymentToolsVM.paymentToolsItems, id: \.self) { paymentTool in
    Button {
        navigationCallback(paymentTool.segueID)
    } label: {
        PaymentToolsRow(paymentToolName: paymentTool.title, imageName: paymentTool.imageName)
            .accessibilityElement()
           .accessibilityIdentifier("Billing_\(paymentTool.title.replacingOccurrences(of: " ", with: ""))")
    }
    if paymentTool != self.paymentToolsVM.paymentToolsItems.last {
          Divider()
    }
}

So you can see the accessibility ID is there, and it shows up properly when I open up Accessibility Inspector with the simulator, but the testing script isn't picking up on it, and it doesn't show up when the view is inspected in Appium. I have other SwiftUI views embedded in the UIKit view, and the script picks up the buttons on those, so I'm not sure what's different about this one.

Here's the script we're using to test (written in Java, using BDD framework):

try {
    WaitForElement.waitForText(driver, "Bill details");
    actualDueAmount = BaseClass.getAmountFromStr(driver.findElement(actualDueAmountIos));
    if (driver.getPageSource().contains("Scheduled"))
        deletePaymentFromManageBill(platform);
    if (driver.getPageSource().contains("Pay")) {
        BaseClass.logInfo("Pay button is available on the screen");
        BaseClass.takeScreenShot(driver);
    } else {
        BaseClass.logFail("Pay button is not available on the screen");
        fail("Pay button is not available on the screen");
    }
                                                
    scroll.scrollDown("Pay bills", platform);
    //WaitForElement.waitForText(driver, "Pay bills");
    BaseClass.clickObject(driver, paybillbutton, "Pay bills");
}

Does anyone have any ideas for what the disconnect could be?

UPDATE: Here's an example of the buttons that are working in the same storyboard:

VStack {
    // some other stuff here

    HStack(spacing: 12) {
        if let leftButton = reminderViewModel.getLeftButtonType() {
            GenericButtonView(text: Text(leftButton.getButtonTitle()), 

                buttonType: leftButton.buttonType, 
                callback: {
                    reminderViewModel.leftButtonSelected(leftButtonType: leftButton, hasAutopay: reminderViewModel.hasAutoPay)
                })
                .accessibilityIdentifier(reminderViewModel.accessibilityObject.leftBillButtonIdentifier)
        }
                        
        GenericButtonView(text: Text(BillingButtonType.billDetails.getButtonTitle()), 
            buttonType: BillingButtonType.billDetails.buttonType, 
            callback: {
                reminderViewModel.rightButtonSelected()
            })
            .accessibilityIdentifier(reminderViewModel.accessibilityObject.rightBillButtonIdentifier)
    }
}

Each of these VStacks is a single cell in the UITableView, but the list of buttons up above are also a single cell. Generic Button View is a custom view to handle all the styling.


Solution

  • So I figured out a workaround (still not sure WHY this worked, but in case anyone else runs into this issue):

    Instead of having a list of rows inside a single storyboard table cell, I updated it so that each row is one cell in the table, and that allows the script and Appium to read the accessibility ID.