XCUITest错误:鼠标左键向下:找不到匹配的元素 - Xcode错误

时间:2016-10-18 19:29:30

标签: macos cocoa appkit xcode-ui-testing nsbutton

我正在为我的macOS应用程序构建UI测试。这是在macOS Sierra上使用Xcode 8。我注意到的一件事是当我记录我的UI测试时,单击我的自定义控件NSButton子类时收到一个奇怪的错误。错误消息为:Recorder Service Error: Left Mouse Down: Failed to find matching element - Xcode error

在Google上搜索此错误时,似乎这是与AppKit中的可访问性或错误相关的问题或两者的某种组合。我使用NSView自定义控件子类(使用mouseDown:覆盖来模拟按钮单击)再次尝试相同的方法,UI测试能够在测试中找到并成功记录此事件。但是,使用NSButton执行此操作时似乎存在一个非常具体的问题。

我试过的其他事情:

在身份检查器中,我确实将Identifier属性设置为特定值,但这似乎对记录我的UI测试没有任何有益影响。

我也试过覆盖:

  override func accessibilityPerformPress() -> Bool {
        return true
    }

但由于NSButton已符合NSAccessibilityButton,这似乎也没有明显影响。

我还尝试在UITest中抛出断点并在Xcode控制台中通过po XCUIApplication()打印整个XCUIApplication树,我注意到我的自定义控件似乎没有出现在树层次结构中。

以下是我的小样本应用程序中我的故事板的概述:

enter image description here

我已经包含了系统按钮(可以找到并正确记录)以及我下面的自定义控件NSButton。

此处还有控制台中XCUIApplication树的快照:

enter image description here

我的NSButton子类的代码如下所示:

@IBDesignable class CustomButton : NSButton {

    //MARK: - Properties

    @IBInspectable var cornerRadius : Float = 0
    @IBInspectable var backgroundColor : NSColor = NSColor.clear
    @IBInspectable var buttonText : String?
    @IBInspectable var textColor : NSColor = NSColor.white
    @IBInspectable var selectedTextColor : NSColor = NSColor.white
    @IBInspectable var borderColor : NSColor = NSColor.clear
    @IBInspectable var fontSize : Int = 13
    @IBInspectable var borderWidth : Float = 1.5
    @IBInspectable var shouldBoldText : Bool = false
    @IBInspectable var shouldUnderlineText : Bool = false

    fileprivate var isSetup = false
    fileprivate var isSelected = false

    internal var buttonTextField : NSTextField?

    //MARK: - Inteface Builder Managemenet

    override func prepareForInterfaceBuilder() {
        configureView()
    }


    override func accessibilityPerformPress() -> Bool {
        return true
    }


    //MARK: - Init

    override func awakeFromNib() {
        super.awakeFromNib()
        configureView()
    }

    //MARK: - View Configuration and Styling


    /// Configures the control UI elements and all styling options.
    internal func configureView() {
        if isSetup == false {
            setAccessibilityElement(true)
            isSetup = true
            configureButtonTextField()
            styleView()
        }
    }

    /// Configures the button text field and applies auto layout.
    fileprivate func configureButtonTextField() {

        buttonTextField = NSTextField(frame: bounds)
        buttonTextField!.alignment = NSTextAlignment.center
        buttonTextField!.isBordered = false
        buttonTextField!.isEditable = false
        buttonTextField!.isSelectable = false
        buttonTextField!.isBezeled = false
        buttonTextField!.drawsBackground = false
        buttonTextField!.translatesAutoresizingMaskIntoConstraints = false

        addSubview(buttonTextField!)

        //Apply the auto layout.

        let horizontalXConstraint = NSLayoutConstraint(item: buttonTextField!, attribute: NSLayoutAttribute.centerX, relatedBy: NSLayoutRelation.equal, toItem: self, attribute: NSLayoutAttribute.centerX, multiplier: 1, constant: 0)

        let verticalYConstraint = NSLayoutConstraint(item: buttonTextField!, attribute: NSLayoutAttribute.centerY, relatedBy: NSLayoutRelation.equal, toItem: self, attribute: NSLayoutAttribute.centerY, multiplier: 1, constant: 0)

        addConstraint(horizontalXConstraint)
        addConstraint(verticalYConstraint)
    }

    /// Applies all the user defined runtime attributes. attriutes all have
    /// fallback values in case none were set in interface builder.
    fileprivate func styleView() {

        wantsLayer = true

        layer?.backgroundColor = backgroundColor.cgColor
        layer?.cornerRadius = CGFloat(cornerRadius)
        layer?.masksToBounds = true

        if let buttonText = buttonText {
            buttonTextField?.stringValue = buttonText
        }

        buttonTextField?.textColor = textColor
        buttonTextField?.textColor = selectedTextColor
        layer?.borderColor = borderColor.cgColor

        layer?.borderWidth = CGFloat(borderWidth)

        if shouldBoldText == true {
            buttonTextField?.font = NSFont.boldSystemFont(ofSize: CGFloat(fontSize))
        } else {
            buttonTextField?.font = NSFont.systemFont(ofSize: CGFloat(fontSize))
        }
    }


    /// Updates the text color for the button text field. Updatse the selected
    /// text color to match the defined color.
    ///
    /// - parameter textColor: The color to change the button textfield text to.
    internal func styleButtonText(textColor : NSColor) {
        self.textColor = textColor
        buttonTextField?.textColor = textColor
        selectedTextColor = textColor
    }

    //MARK: - Click Management

    override func mouseDown(with event: NSEvent) {


        isSelected = true
        alphaValue = 0.7
        buttonTextField?.textColor = selectedTextColor

    }

    override func mouseUp(with event: NSEvent) {

        alphaValue = 1.0
        buttonTextField?.textColor = textColor
        isSelected = false

        guard let target = target, let action = action else {
            return
        }

        NSApp.sendAction(action, to: target, from: self)

    }

    //MARK: - Cursor Rect Management

    override func resetCursorRects() {
        addCursorRect(bounds, cursor: NSCursor.pointingHand())
    }
}

我对这个很难过。系统控件似乎在UITesting中记录并正常工作,但自定义控件(至少是NSButton)似乎会导致问题。如果有人对可能导致这种情况的任何想法有任何想法,我将不胜感激。

0 个答案:

没有答案