Слив Автоматизация мобильных приложений через ZennoPoster и Appium

?

хотите еще такие статьи?

Голосование закрыто 12 фев 2020.
  1. да

    1 голосов
    100,0%
  2. нет

    0 голосов
    0,0%
Можно выбрать сразу несколько вариантов.
  1. Новичок
    ShprotKakShprot

    Сообщения:
    14
    Репутация:
    10
    Для начала нужно установить все компоненты

    https://github.com/appium/appium-desktop/releases - Сам аппиум

    [​IMG]
    Appium

    https://www.oracle.com/technetwork/java/javase/downloads/2133151 - JRE

    [​IMG]
    JDK
    Дальше устанавливаем эмулятор, которым хотим пользоваться (если его еще нет), лично я использую Genymotion (Если что он бесплатный, регистрируемся и скачиваем For Personal Use)

    Прописываем ANDROID_HOME:

    Жмем правой кнопкой по "Моему компьютеру" -> Свойства -> Дополнительные параметры системы -> Переменные среды -> Создать -> Вписываем имя переменной ANDROID_HOME и путь до exe файла эмулятора -> Сохраняем.

    [​IMG]
    Добавление переменной среды
    Все те же действия проделываем для добавления еще одной переменной JAVA_HOME и путь до установленного JRE

    [​IMG]
    Добавление переменной среды
    Далее запускаем эмулятор или несколько, потом заходим в папку с эмулятором и ищем там adb.exe (он обычно или в основной папке(с основным ехе) или в папках bin или tools. Зажимаем клавишу Shift и жмем правой кнопкой мыши по пустому месту -> Выбираем "Открыть окно команд"

    [​IMG]
    Открыть окно команд
    Или же просто открываем командную строку и прописываем cd и путь до папки с adb.exe, в моем случае это cd C:\Program Files\Genymobile\Genymotion\tools

    [​IMG]
    Командная строка CMD
    Теперь вписываем команду adb devices

    Видим лист девайсов, если не видим лист, то перезапускаем эмуляторы или даже компьютер(Обычно помогает именно перезагрузка компьютера). (Не помогло? Такое бывает очень редко, но скорей всего это какие-то конфликты adb с вашим эмулятором, пробуем использовать другой эмулятор).

    После вписываем adb -s ип эмулятора shell

    В моем случае это выглядит так adb -s 192.168.176.102:5555 shell

    [​IMG]
    adb shell
    После этого устанавливаем нужное приложение на эмулятор и запускаем его, в консоль пишем команду dumpsys window windows | grep -E 'mCurrentFocus|mFocusedApp'

    Получаем данные о запущенном приложении, отсюда нам нужен PACKAGE и ACTIVITY

    Сохраняем эти данные они нам еще пригодятся

    [​IMG]
    Current Focused App
    Запускаем Appium и жмем Start Server

    [​IMG]
    Appium
    Далее жмем на значок лупы

    [​IMG]
    Appium
    Теперь нам нужно задать Capabilities, соответственно вписываем имя пакета, активити, platformName и deviceName - любые, autoGrantPermissions - по дефолту true ставим всегда. Самое нужное это udid - это ип нашего эмулятора.

    {
    "appPackage": "com.android.settings",
    "appActivity": "com.android.settings.Settings",
    "platformName": "Android",
    "autoGrantPermissions": true,
    "deviceName": "Android",
    "udid": "192.168.176.102:5555"
    }

    [​IMG]
    Capabilities
    Жмем Start Session и в появившемся окне жмем на глазик(для записи действий)

    [​IMG]
    Запись действий Appium
    Теперь выполняем действие.

    [​IMG]
    Выполнение действия через Appium
    Отлично, появился код этого действия, мы его можем перевести в другой язык программирования, к сожалению C# тут нету, но это не проблема, т.к. очень легко с питона можно перевести все на C#

    [​IMG]
    Выбор ЯП
    Если вдруг в приложении вылезает реклама, то жмем галочку назад

    [​IMG]
    driver.Navigate().Back();
    Записываем все нужные нам действия.

    Перейдем к автоматизации через ZennoPoster

    Закидываем appium-dotnet-driver.dll и WebDriver.dll в Progs/ExternalAssemblies

    Ссылки на dll'ки appium-dotnet-driver.dll и WebDriver.dll

    [​IMG]
    Закидываем библиотеки в ZennoPoster
    Теперь создаем новый проект или открываем ваш старый, заходим в Ссылки из GAC, жмем кнопку добавить, указываем путь до наших dll'ок и жмем "ОК".

    [​IMG]
    Добавляем библиотеки в ZennoPoster
    Открываем Директивы Using и вписываем следующее:

    using OpenQA.Selenium;

    using OpenQA.Selenium.Appium;

    using OpenQA.Selenium.Appium.Android;

    using OpenQA.Selenium.Remote;

    Если вдруг будут в будущем какие-то ошибки связанные с WebDriver, можно будет дописать using OpenQA.Selenium.WebDriver;

    [​IMG]
    Директивы Using
    Теперь заходим в общий код и создаем несколько функций, тут вам нужно изменить только path (это путь до adb.exe в папке с эмулятором).

    public static string path = @"C:\Program Files\Genymobile\Genymotion\tools";

    public static List<string> GetEmulators()

    {

    List<string> ips = new List<string>();

    var lines = new List<string>()

    {

    @"cd "+path,

    "adb devices",

    };

    string[] result = WriteCMD(lines);

    foreach (string r in result)

    {

    var matches = Regex.Matches(r, @"\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}:\d{1,6}", RegexOptions.Singleline);

    foreach (Match match in matches)

    {

    ips.Add(match.Value);

    }

    }

    return ips;

    }

    private static string[] WriteCMD(List<string> lines)

    {

    Process process = new Process();

    process.StartInfo.FileName = "cmd.exe";

    process.StartInfo.RedirectStandardInput = true;

    process.StartInfo.RedirectStandardOutput = true;

    process.StartInfo.CreateNoWindow = false;

    process.StartInfo.UseShellExecute = false;

    process.Start();

    foreach (var line in lines)

    {

    process.StandardInput.WriteLine(line);

    process.StandardInput.Flush();

    }

    process.StandardInput.Close();

    process.WaitForExit();

    return process.StandardOutput.ReadToEnd().Split('\n');

    }

    [​IMG]
    C# код для получения Ип эмуляторов.
    Соответственно откуда в общем коде мы можем получить список эмуляторов так: List<string> Emulators = GetEmulators();

    Или же в самом проекте создаем общий код C# и в код пишем так: List<string> Emulators = ZennoLab.OwnCode.CommonCode.GetEmulators();

    Дальше вписываем Capabilities:

    string ip = Emulators[0];

    project.SendInfoToLog(ip, true);

    DesiredCapabilities capabilities = new DesiredCapabilities();

    capabilities.SetCapability("device", "Android");

    capabilities.SetCapability("appPackage", "com.android.settings");

    capabilities.SetCapability("appActivity", "com.android.settings.Settings"); capabilities.SetCapability("deviceName", "Android");

    capabilities.SetCapability("platformName", "Android");

    capabilities.SetCapability("udid", ip);

    AndroidDriver<OpenQA.Selenium.IWebElement> driver = new AndroidDriver<OpenQA.Selenium.IWebElement>(new Uri("http://127.0.0.1:4723/wd/hub"), capabilities);

    Соответственно тут заполняем все так же, как делали до этого в Appium'е

    Отлично, подключение к девайсу(девайсам) мы сделали, теперь нам надо переписать наш Python код на C#

    Было такое:

    el1 = driver.find_element_by_id("com.neenbo:id/iv_ola")

    el1.click()

    el2 = driver.find_element_by_id("com.neenbo:id/iv_sim")

    el2.click()

    el3 = driver.find_element_by_id("com.neenbo:id/iv_nao")

    el3.click()

    driver.back()

    el4 = driver.find_element_by_id("com.neenbo:id/iv_menu_toolbar")

    el4.click()

    el5 = driver.find_element_by_xpath("(//android.widget.ImageView[@content-desc=\"IMAGE\"])[6]")

    el5.click()

    Как это переписать? Все просто, в основном в C# все слова пишутся с большой буквы и нижнее подчеркивание "_" не используется, соответственно где было driver.find_element_by_id мы пишем driver.FindElementById

    Вконце всегда ставим точку с запятой ";"

    Перед всеми элементами пишем var, т.е. там, где было el1 мы пишем var el1

    вот пример первых двух строк:

    var el1 = driver.FindElementById("com.neenbo:id/iv_ola");

    el1.Click();

    Или можно сделать проще:

    driver.FindElementById("com.neenbo:id/iv_ola").Click();

    Так же во время переписывания кода зенка нам будет давать подсказки

    [​IMG]
    ZennoPoster Appium
    Получился вот такой код:

    [​IMG]
    Код C#
    List<string> ips = ZennoLab.OwnCode.CommonCode.GetEmulators(); // получаем ип эмуляторов в коллекцию.

    foreach(string ip in ips) // перебираем все строки из коллекции

    {

    DesiredCapabilities capabilities = new DesiredCapabilities(); // класс настроек

    capabilities.SetCapability("device", "Android"); // Любое имя

    capabilities.SetCapability("appPackage", "com.android.settings"); // Package

    capabilities.SetCapability("appActivity", "com.android.settings.Settings"); //Activity

    capabilities.SetCapability("deviceName", "Android"); //Любое имя

    capabilities.SetCapability("platformName", "Android"); //Любое имя

    capabilities.SetCapability("udid", ip); // адрес нашего эмулятора

    var driver = OpenQA.Selenium.Appium.Android.AndroidDriver<OpenQA.Selenium.Appium.Android.AndroidDriver>(new Uri("http://127.0.0.1:4723/wd/hub"), capabilities); // инициализируем эмулятор

    driver.StartActivity("com.neenbo", "com.neenbo.LoginActivity"); // Запускаем приложение

    driver.FindElementById("com.neenbo:id/iv_menu_toolbar").Click(); // Ищем элемент по ид и кликаем по нему

    driver.FindElementByXPath("(//android.widget.ImageView[@content-desc=\"IMAGE\"])[3]").Click(); // Ищем элемент и кликаем по нему

    for(int i=0;i<50;i++) // Цикл, чтобы выполнить действия 50 раз

    {

    try // Заключаем в try { } catch { } чтобы в тот момент, когда вылезет реклама нажать кнопку назад driver.Navigate().Back();

    {

    driver.FindElementById("com.neenbo:id/iv_ola").Click(); // Ищем элемент и кликаем по нему

    driver.FindElementById("com.neenbo:id/iv_ola").Click(); // Ищем элемент и кликаем по нему

    driver.FindElementById("com.neenbo:id/iv_sim").Click(); // Ищем элемент и кликаем по нему

    driver.FindElementById("com.neenbo:id/iv_nao").Click(); // Ищем элемент и кликаем по нему

    }

    catch // Ловим ошибку (Ошибка будет говорить о том, что элемент не существует)

    {

    driver.Navigate().Back(); // Жмем кнопку назад

    }

    }

    }

    Совсем забыл, нужно же добавить задержки, делается в коде это так:

    System.Threading.Thread.Sleep(5000); // Ожидание 5 секунд (5000 миллисекунд это 5 секунд)



    У некоторых людей(или с некоторыми версиями dll'ок, не знаю) существует проблема в этом месте OpenQA.Selenium.Appium.Android.AndroidDriver<OpenQA.Selenium.Appium.Android.AndroidDriver>(new Uri("http://127.0.0.1:4723/wd/hub"), capabilities); // инициализируем эмулятор

    Самое простое решение, которое я нашел это заменить AndroidDriver на IWebDriver.

    IWebDriver driver = new RemoteWebDriver(new Uri("http://127.0.0.1:4723/wd/hub"), capabilities);

    Тогда код получается немного другой

    Разница в том, что вместо driver.FindElementById("com.neenbo:id/iv_ola").Click(); нужно будет писать так: driver.FindElement(By.Id("com.neenbo:id/iv_ola")).Click();

    [​IMG]
    C# код
    List<string> ips = ZennoLab.OwnCode.CommonCode.GetEmulators(); // получаем ип эмуляторов в коллекцию.

    foreach(string ip in ips) // перебираем все строки из коллекции

    {

    DesiredCapabilities capabilities = new DesiredCapabilities(); // класс настроек

    capabilities.SetCapability("device", "Android"); //Любое имя

    capabilities.SetCapability("appPackage", "com.neenbo"); // Package

    capabilities.SetCapability("appActivity", "com.neenbo.LoginActivity"); //Activity

    capabilities.SetCapability("deviceName", "Android"); //Любое имя

    capabilities.SetCapability("platformName", "Android"); //Любое имя

    capabilities.SetCapability("udid", ip); // адрес нашего эмулятора

    IWebDriver driver = new RemoteWebDriver(new Uri("http://127.0.0.1:4723/wd/hub"), capabilities); // инициализируем эмулятор

    System.Threading.Thread.Sleep(25000); // Задержка 25 секунд

    driver.FindElement(By.Id("com.neenbo:id/iv_menu_toolbar")).Click(); // Ищем элемент и кликаем по нему

    System.Threading.Thread.Sleep(5000); // Задержка 5 секунд

    driver.FindElement(By.XPath("(//android.widget.ImageView[@content-desc=\"IMAGE\"])[3]")).Click(); // Ищем элемент и кликаем по нему

    System.Threading.Thread.Sleep(5000); // Задержка 5 секунд

    for(int i=0;i<50;i++) // Цикл, чтобы выполнить действия 50 раз

    {

    try // Заключаем в try { } catch { } чтобы в тот момент, когда вылезет реклама нажать кнопку назад driver.Navigate().Back();

    {

    System.Threading.Thread.Sleep(5000); // Задержка 5 секунд

    driver.FindElement(By.Id("com.neenbo:id/iv_ola")).Click(); // Ищем элемент и кликаем по нему

    System.Threading.Thread.Sleep(5000); // Задержка 5 секунд

    driver.FindElement(By.Id("com.neenbo:id/iv_ola")).Click(); // Ищем элемент и кликаем по нему

    System.Threading.Thread.Sleep(5000); // Задержка 5 секунд

    driver.FindElement(By.Id("com.neenbo:id/iv_sim")).Click(); // Ищем элемент и кликаем по нему

    System.Threading.Thread.Sleep(5000); // Задержка 5 секунд

    driver.FindElement(By.Id("com.neenbo:id/iv_nao")).Click(); // Ищем элемент и кликаем по нему

    }

    catch // Ловим ошибку (Ошибка будет говорить о том, что элемент не существует)

    {

    driver.Navigate().Back(); // Жмем кнопку назад

    }

    }

    }



    МУЛЬТИПОТОК

    Итак, как все настроить и запустить мы разобрались, но код выполняется синхронно, эмуляторы работаю по порядку! Хочу чтобы все работало одновременно, что делать? - Для этого нужно немного изменить код программы, весь код который мы писали перенесем в общий код программы и будем вызывать это все через Task.Run(()=>.....)

    Весь наш написанный скрипт мы перенесем в отдельную функцию и в качестве параметра в нее будем передавать ип эмулятора

    Не забываем добавлять ссылки на библиотеки:

    using OpenQA.Selenium.Appium;

    using OpenQA.Selenium.Appium.Android;

    using OpenQA.Selenium.Remote;

    using OpenQA.Selenium;

    using System.Threading.Tasks;

    Вот часть того, что у нас получилось. Соответственно из самого проекта зенки будем вызывать функцию Start();

    [​IMG]
    C# код
    public static async Task Start() //Для запуска работы в мультипоток

    {

    List<string> ips = GetEmulators(); // получаем ип эмуляторов в коллекцию.

    List<Task> Tasks = new List<Task>(); // Создаем новую коллекцию, куда будем записывать наши потоки

    foreach(string ip in ips) // перебираем все строки из коллекции

    {

    Tasks.Add(Task.Run(()=>StartWork(ip))); // Запускаем работу эмулятора

    await Task.Delay(1000); // Сделаем небольшую задержку между запуском потоков

    }

    await Task.WhenAll(Tasks);// Ждем когда все потоки завершат работу

    }



    private static async Task StartWork(string ip)

    {

    await Task.Delay(100); // Чтобы все выполнялось правильно нужен хотя бы 1 await в функции

    DesiredCapabilities capabilities = new DesiredCapabilities(); // класс настроек

    capabilities.SetCapability("device", "Android"); //Любое имя

    capabilities.SetCapability("appPackage", "com.neenbo"); // Package

    capabilities.SetCapability("appActivity", "com.neenbo.LoginActivity"); //Activity

    capabilities.SetCapability("deviceName", "Android"); //Любое имя

    capabilities.SetCapability("platformName", "Android"); //Любое имя

    capabilities.SetCapability("udid", ip); // адрес нашего эмулятора

    IWebDriver driver = new RemoteWebDriver(new Uri("http://127.0.0.1:4723/wd/hub"), capabilities); // инициализируем эмулятор

    System.Threading.Thread.Sleep(25000); // Задержка 25 секунд

    driver.FindElement(By.Id("com.neenbo:id/iv_menu_toolbar")).Click(); // Ищем элемент и кликаем по нему

    System.Threading.Thread.Sleep(5000); // Задержка 5 секунд

    driver.FindElement(By.XPath("(//android.widget.ImageView[@content-desc=\"IMAGE\"])[3]")).Click(); // Ищем элемент и кликаем по нему

    System.Threading.Thread.Sleep(5000); // Задержка 5 секунд

    for(int i=0;i<50;i++) // Цикл, чтобы выполнить действия 50 раз

    {

    try // Заключаем в try { } catch { } чтобы в тот момент, когда вылезет реклама нажать кнопку назад driver.Navigate().Back();

    {

    System.Threading.Thread.Sleep(5000); // Задержка 5 секунд

    driver.FindElement(By.Id("com.neenbo:id/iv_ola")).Click(); // Ищем элемент и кликаем по нему

    System.Threading.Thread.Sleep(5000); // Задержка 5 секунд

    driver.FindElement(By.Id("com.neenbo:id/iv_ola")).Click(); // Ищем элемент и кликаем по нему

    System.Threading.Thread.Sleep(5000); // Задержка 5 секунд

    driver.FindElement(By.Id("com.neenbo:id/iv_sim")).Click(); // Ищем элемент и кликаем по нему

    System.Threading.Thread.Sleep(5000); // Задержка 5 секунд

    driver.FindElement(By.Id("com.neenbo:id/iv_nao")).Click(); // Ищем элемент и кликаем по нему

    }

    catch // Ловим ошибку (Ошибка будет говорить о том, что элемент не существует)

    {

    driver.Navigate().Back(); // Жмем кнопку назад

    }

    }

    }



    Делаем вызов нашей функции:

    ZennoLab.OwnCode.CommonCode.Start();

    [​IMG]
    Вызов функции из общего кода
    Видео работы

    Код проекта

    Основные команды, которые используются в работе обычно:

    driver.Tap(1, 436, 694, 0); // Нажатие по координатам

    driver.Swipe(414, 660, 422, 1160, 0); свайп с координатов 414 660 до 422 1160

    driver.FindElementById("n.android:id/Title").Text // Получение текста элемента.

    driver.FindElementById("n.android:id/button").Click(); // Клик по элементу

    driver.FindElementById("n.android:id/text").SendKeys("Привет"); // Ввод текста

    driver.FindElementById("n.android:id/text").Clear(); // Очистка текстового поля

    driver.Navigate().Back(); // Возврат назад

    driver.Quit(); // Закрытие сессии

    driver.RemoveApp("com.neenbo"); // Удаление апк (Используется имя Package

    driver.InstallApp(Environment.CurrentDirectory + "\\someapk.apk"); // Установка приложения(в параметрах указываем путь до приложения)



    Возможные проблемы:

    1. Вылетает из аккаунта - Значит открываем приложение с использованием неправильного Activity, пробуем заменить Activity
    2. Начало выдавать ошибку что устройство не найдено или не находит эмуляторы через adb devices, хотя раньше все работало - Лечим перезагрузкой девайсов или компьютера
    3. Выдает с самого начала ошибку/не находит эмуляторы - Пробуем создать эмулятор с другим андройдом, например, 7 или 8. Если не помогает, то скачиваем с гитхаба разные версии библиотек. На некоторых версиях библиотек и эмуляторов такое бывает и с этим ничего не поделать, нужно подбирать версию под себя.
    4. Не видит элементы - Увеличиваем задержки, если не помогает, то кликаем по координатам
    5. Через какое-то время в процессе работы в мультипотоке один или несколько эмуляторов отваливаются - Это нормально, аппиум не предназначен для мультипотока, используем try { } catch { } который заключаем в while(true) { } для автоматического перезапуска работы.

      P.s буду благодарен за + в репу
     
    Последнее редактирование: 9 фев 2020
    Neuronsoft нравится это.
  2. Пользователь
    Ahmed ibn Senatra

    Сообщения:
    101
    Репутация:
    23
    странно как эта статья не приняла участия в конкурсе на самом форуме Зенки, уверен что она была бы топовой
     
  3. Новичок
    robertheorh

    Сообщения:
    36
    Репутация:
    7
    Эх, проще по запросам научиться работать чем зенку покупать и разбираться в этих софтах)
     
  4. Пользователь
    Ahmed ibn Senatra

    Сообщения:
    101
    Репутация:
    23
    не надо все делать, как дамочки три действия одновременно, работаем по запросам, попутно на втором мониторе курс по зенке и добавочно ещё торгуем на криптобирже :)
     
  5. Новичок
    alkornef

    Сообщения:
    23
    Репутация:
    0
    столько с зенкой мороки было при работе с эмулем, ужос
     
  6. Новичок
    shottalols

    Сообщения:
    1
    Репутация:
    1
    Очень годно и подробно описано , но человеку далекому от программирования сложно)

    PS как поставить + в репу не разобрался xD
     
    Neuronsoft нравится это.
  7. Новичок
    spbalexpiter

    Сообщения:
    34
    Репутация:
    6
    жаль нельзя масштабировать
     
  8. Новичок
    markzukerberg

    Сообщения:
    5
    Репутация:
    0
    + очень круто. А почему не на форуме зенки?
     
CCv