Detox: iOS Simulator как подтвердить предупреждающее сообщение

Я использую Alert от react-native.

Как получить детокс, нажав кнопку «Выйти» в предупреждающем сообщении?

введите описание изображения здесь

Я пробовал использовать await element(by.text('Log out')).tap();

Но я получаю ошибку «Несколько элементов совпадают». Предположительно он находит 3 элемента с одинаковой меткой. Исходная кнопка с меткой «Выйти», используемая для запуска предупреждающего сообщения, заголовок предупреждающего сообщения и кнопка предупреждающего сообщения, которую я хочу нажать.

Error Trace: [
  {
    "Description" : "Multiple elements were matched: (
    "<UILabel:0x7fe7964db910; AX=Y; AX.label='Log out'; AX.frame={{41, 234}, {238, 20.5}}; AX.activationPoint={160, 244.25}; AX.traits='UIAccessibilityTraitStaticText'; AX.focused='N'; frame={{16, 20}, {238, 20.5}}; opaque; alpha=1; UIE=N; text='Log out'>",
    "<UILabel:0x7fe7964dda90; AX=Y; AX.label='Log out'; AX.frame={{198.5, 322.5}, {58, 20.5}}; AX.activationPoint={227.5, 332.75}; AX.traits='UIAccessibilityTraitStaticText'; AX.focused='N'; frame={{0, 12}, {58, 20.5}}; opaque; alpha=1; UIE=N; text='Log out'>",
    "<RCTText:0x7fe79652f300; AX=Y; AX.label='Log out'; AX.frame={{16, 338.5}, {288, 17}}; AX.activationPoint={160, 347}; AX.traits='UIAccessibilityTraitStaticText'; AX.focused='N'; frame={{0, 0}, {288, 17}}; alpha=1>"
). Please use selection matchers to narrow the selection down to single element.",
    "Error Domain" : "com.google.earlgrey.ElementInteractionErrorDomain",
    "Error Code" : "5",
    "File Name" : "GREYElementInteraction.m",
    "Function Name" : "-[GREYElementInteraction grey_errorForMultipleMatchingElements:withMatchedElementsIndexOutOfBounds:]",
    "Line" : "956"
  }
]

Я предполагаю, что один из способов - использовать .atIndex(), но это означает, что мне нужно играть с индексами каждый раз, когда что-то меняется, чтобы определить правильный элемент.

Нет лучшего способа решить эту проблему?

Спасибо.


person Antoni4    schedule 28.11.2017    source источник


Ответы (4)


После некоторой работы я в конечном итоге использовал это:

await element(by.label('Log out').and(by.type('_UIAlertControllerActionView'))).tap();

Не уверен, будет ли это работать для каждой версии iOS, но, похоже, работает на 10.3 и 11.1.

Используйте отладчик иерархии представления, предоставляемый Xcode, чтобы узнать, изменился ли тип для другой версии iOS.

person Antoni4    schedule 28.11.2017
comment
Отличная находка! Но как вы узнали, что это _UIAlertControllerActionView ? Что, если нам нужно просмотреть, например, фотогалерею, нажать на изображение и нажать кнопку Choose? - person mjakic; 12.04.2018
comment
Привет, я полагаю, что использовал Debug View Hierarchy из Xcode для этого - person Antoni4; 16.04.2018
comment
будет ли это работать для окон предупреждений, открытых системой? например, спрашивать разрешения у пользователя. - person arjun; 01.05.2018
comment
Привет, только что попробовал это для себя в своем проекте, и библиотека детоксикации не находит элемент. Есть ли другой способ? - person jaumevn; 18.05.2018
comment
Привет, есть ли способ узнать типы элементов пользовательского интерфейса с помощью тестов Expo для детоксикации, таких как иерархия представления отладки, о которой вы упоминали ранее? - person srikanth; 03.07.2018
comment
@arjun, похоже, не работает для окон предупреждений, открытых системой. Я попытался использовать это решение, заменив «Выйти» на «Разрешить» (для разрешения push-уведомлений), но Detox все равно завершает работу с Error: Error: Cannot find UI element. - person Pat Needham; 20.08.2018
comment
К сожалению, он не работает на iOS 12 и не поддерживает реакцию, есть ли помощь? - person Mark; 06.10.2018
comment
@Mark пробовали ли вы использовать отладчик иерархии представлений, предоставляемый Xcode, чтобы узнать, изменился ли тип в iOS 12? - person Antoni4; 10.10.2018
comment
Я проверил Debug View Hierarchy в Xcode в iOS 12.2. Каждая метка Confirm и Cancel представляет собой RCTView, содержащее RCTTextView. - person Leo; 25.06.2019
comment
Я включил разрешение в init.js файле детоксикации, и предупреждение больше не отображается, но, как описано в Лео Натан - восстановить Монику предупреждение отображается в процессе, отличном от того, в котором работает Детокс, и с ним невозможно взаимодействовать. Похоже, что обсуждение этого вопроса ограничено SO - person Fabrizio Bertoglio; 20.12.2019
comment
Он работает для iOS, для Android здесь: stackoverflow.com/a/59737117/551744 - person Chaki_Black; 20.08.2020

Он должен работать с поиском элемента по тексту

await element(by.text('Log out')).tap();

Демо-репозиторий: https://github.com/FDiskas/demonas/blob/c703840a991b2f3d96a18ac8c5120ee1d5f901f8/e2e/firstTest.spec.ts#L11

person FDisk    schedule 14.01.2020
comment
Он работает для Android, для iOS здесь: stackoverflow.com/a/47522589/551744 - person Chaki_Black; 20.08.2020

Теперь вы можете нажимать на родные диалоги. Проверено на iOS. (не тестировал на Android)

Если на вашей кнопке написано «ОК», то есть:

Alert.alert(
  `Are you sure you would like to remove this image as the coming soon image?`,
  undefined,
  [
    {
      text: "No",
      style: "cancel",
    },
    {
      text: "OK",
      style: "destructive",
      onPress: this.onRemoveHero,
    },
  ]
);

Вы бы щелкнули по нему, выполнив:

element(by.label("OK")).atIndex(0).tap();
person Noitidart    schedule 04.12.2019
comment
Это отлично работает с детокс 17.0.2, который нарушил некоторые способы нацеливания на такие элементы, как Alert в RN (вы больше не можете настраивать кнопки предупреждений с помощью простого by.text('OK') - person Dantereve; 29.06.2020
comment
@Dantereve, не могли бы вы уточнить, by.text('OK') раньше работал? Но теперь единственный способ сделать это с by.label('OK')? - person Noitidart; 29.06.2020
comment
да, by.text('OK') работал с Detox 16.x, но больше не работал с Detox 17 в обоих приложениях, которые я сейчас тестирую с помощью Detox. Исправление заключалось в использовании element(by.label("OK")).atIndex(0). Это, безусловно, связано со следующим: Detox Issue 2156 - person Dantereve; 30.06.2020

Я написал служебную функцию, которая позволяет вам делать эту кроссплатформенную работу.

Функция

/**
 * Detects a systme dialog button by label
 * 
 * @param {string} label
 * 
 * @returns {*}
 */
export function systemDialog(label){
    if (device.getPlatform() === 'ios') {
        return element(by.label(label)).atIndex(0);
    }

    return element(by.text(label));
}

использование

import { systemDialog } from "path to system dialog";

...

await systemDialog('OK').tap();
person Luke Brandon Farrell    schedule 25.01.2021