Как предоставить пользовательские возможности на сервере селена?

Я знаю, что некоторые возможности селена можно получить с помощью метода, один из них такой:

driver.getCapabilities().getBrowserName();

Он возвращает значение имени браузера.

Но если это относится к доступному методу, если я не ошибаюсь, это, похоже, связано с пользовательскими возможностями, например, я имею в виду:

driver.getCapabilities().getCapability("something ?");

Возвращает: значение или ноль, если оно не задано.

получить возможности

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

    private RemoteWebDriver driver;
    private URL url;
    private DesiredCapabilities dc = new DesiredCapabilities();

    @Before
    public void setUp() throws MalformedURLException {
        url = new URL("http://localhost:4444/wd/hub");
        dc.setCapability(CapabilityType.BROWSER_NAME, BrowserType.CHROME);
        //this is custom capability i mean
        dc.setCapability("testName", "Login");
        driver = new RemoteWebDriver(url, dc);
    }
    
    @Test
    public void test() {
        some code.....
    }
    
    @After
    public void tearDown() {
        System.out.println("Browser Name : "+ driver.getCapabilities().getCapability("browserName"));
        System.out.println("Test Name : "+ driver.getCapabilities().getCapability("testName"));
        driver.quit();
    }

С json журнал сервера говорит:

Capabilities are: {
  "browserName": "chrome",
  "testName": "Login"
}

журнал сервера

Но я получаю значение null.

Как правильно настроить? Как сделать так, чтобы наш сервер предоставлял возможности testName, я имею в виду? и можно получить за driver.getCapabilities().getCapability("testName");

Текущий результат Browser Name : chrome Test Name : null

Ожидаемый результат Browser Name : chrome Test Name : Login

Спасибо заранее


person frianH    schedule 05.08.2019    source источник
comment
w3.org/TR/webdriver1/#capabilities это может помочь понять возможности . Удаленный конец не будет возвращать значения, если он не поддерживается.   -  person Rahul L    schedule 05.08.2019
comment
@RahulL да, правильно, если я использую .getCapability("browserName") platformName и т. д., он вернет значение, но оно по-прежнему доступно по умолчанию в селене. Я использовал платную тестовую платформу (платформа на основе селена и аппиума), и для целей имени отчета я могу настроить только добавление метода dc.setCapability("testName"," Login "), и я могу получить значение testName с помощью метода .getCapability ("testName"), даже я могу также получите значение URL-адреса отчета, используя метод .getCapability ("urlReport"). Поэтому я предполагаю, что имя возможности может быть произвольным по мере необходимости.   -  person frianH    schedule 05.08.2019
comment
Но на самом деле все не так просто, как я себе представляю   -  person frianH    schedule 05.08.2019
comment
Sauce lab или Browser stack имеют собственные реализации удаленных серверов. Они не используют удаленный сервер selenium как есть. Таким образом, сервер распознает определенные им возможности. Пример github.com/aerokube/selenoid, реализованный на языке go   -  person Rahul L    schedule 05.08.2019
comment
Итак, вы имеете в виду, что возможности, которые я имею в виду, сделаны отдельно от фреймворка Selenium?   -  person frianH    schedule 05.08.2019
comment
Ответ: Да. В соответствии с протоколом W3C — «Удаленные концы могут также предоставлять возможности расширения, которые являются дополнительными возможностями, используемыми для обеспечения конфигурации или удовлетворения других потребностей конкретного поставщика». Возможности dc.setCapability (testName, Login). будет игнорироваться удаленным сервером. Когда вы запросите его обратно, он ничего не отправит.   -  person Rahul L    schedule 05.08.2019
comment
Давайте продолжим это обсуждение в чате.   -  person frianH    schedule 05.08.2019


Ответы (2)


Вы можете извлечь Возможности WebDriver, например. Browser Name, Browser Version, Platform Name и т. д., используя одно из следующих решений:

  • Использование прямых API:

    • Блок кода:

      System.out.println("Class Name is : "+((RemoteWebDriver) driver).getCapabilities().getClass().toString());
      System.out.println("Browser Name is : "+((RemoteWebDriver) driver).getCapabilities().getBrowserName().toLowerCase());
      System.out.println("Browser Version is : "+((RemoteWebDriver) driver).getCapabilities().getVersion().toString());
      System.out.println("Platform Name is : "+((RemoteWebDriver) driver).getCapabilities().getPlatform().toString());
      
    • Выход консоли:

      Class Name is : class org.openqa.selenium.MutableCapabilities
      Browser Name is : firefox
      Browser Version is : 67.0
      Platform Name is : WINDOWS
      
  • Использование getCapability():

    • Блок кода:

      Capabilities cap = ((RemoteWebDriver) driver).getCapabilities();
      System.out.println("acceptInsecureCerts value is: "+cap.getCapability("acceptInsecureCerts"));
      System.out.println("Browser Name is : "+cap.getBrowserName());
      System.out.println("Browser version is : "+cap.getVersion());           
      System.out.println("Platform is : "+cap.getPlatform().toString());
      System.out.println("javascriptEnabled value is: "+cap.getCapability("javascriptEnabled"));
      System.out.println("moz:accessibilityChecks value is: "+cap.getCapability("moz:accessibilityChecks"));
      System.out.println("moz:buildID value is: "+cap.getCapability("moz:buildID"));
      System.out.println("geckodriverVersion value is: "+cap.getCapability("geckodriverVersion"));
      System.out.println("Headless Mozilla value is: "+((RemoteWebDriver) driver).getCapabilities().getCapability("moz:headless"));
      System.out.println("moz:headless value is: "+cap.getCapability("moz:headless"));
      System.out.println("Mozilla Profile value is : "+ ((RemoteWebDriver) driver).getCapabilities().getCapability("moz:profile"));
      System.out.println("moz:processID value is : "+cap.getCapability("moz:processID"));
      System.out.println("moz:profile value is : "+cap.getCapability("moz:profile"));
      System.out.println("moz:shutdownTimeout value is : "+cap.getCapability("moz:shutdownTimeout"));
      System.out.println("moz:useNonSpecCompliantPointerOrigin value is : "+cap.getCapability("moz:useNonSpecCompliantPointerOrigin"));
      System.out.println("moz:webdriverClick value is : "+cap.getCapability("moz:webdriverClick"));
      System.out.println("pageLoadStrategy value is : "+cap.getCapability("pageLoadStrategy"));
      System.out.println("Platform is : "+cap.getPlatform().toString());
      System.out.println("platformName value is : "+cap.getCapability("platformName"));
      System.out.println("platformVersion value is : "+cap.getCapability("platformVersion"));
      System.out.println("rotatable value is : "+cap.getCapability("rotatable"));
      System.out.println("setWindowRect value is : "+cap.getCapability("setWindowRect"));
      System.out.println("strictFileInteractability value is : "+cap.getCapability("strictFileInteractability"));
      System.out.println("timeouts values are : "+cap.getCapability("timeouts"));
      System.out.println("unhandledPromptBehavior value is : "+cap.getCapability("unhandledPromptBehavior"));
      
    • Выход консоли:

      acceptInsecureCerts value is: true
      Browser Name is : firefox
      Browser version is : 67.0
      Platform is : WINDOWS
      javascriptEnabled value is: true
      moz:accessibilityChecks value is: false
      moz:buildID value is: 20190516215225
      geckodriverVersion value is: null
      Headless Mozilla value is: false
      moz:headless value is: false
      Mozilla Profile value is : C:\Users\Debanjan.B\AppData\Local\Temp\rust_mozprofile.7HI7QUtzF1YP
      moz:processID value is : 7308
      moz:profile value is : C:\Users\Debanjan.B\AppData\Local\Temp\rust_mozprofile.7HI7QUtzF1YP
      moz:shutdownTimeout value is : 60000
      moz:useNonSpecCompliantPointerOrigin value is : false
      moz:webdriverClick value is : true
      pageLoadStrategy value is : normal
      Platform is : WINDOWS
      platformName value is : WINDOWS
      platformVersion value is : 6.2
      rotatable value is : false
      setWindowRect value is : true
      strictFileInteractability value is : false
      timeouts values are : {implicit=0, pageLoad=300000, script=30000}
      unhandledPromptBehavior value is : dismiss and notify
      

Вы можете найти список поддерживаемых возможностей в разделе Возможности в разделе Рекомендация W3C для веб-драйвера

person DebanjanB    schedule 05.08.2019
comment
Спасибо. Но browserName browserVersion platformName - это возможность по умолчанию из селена, мне нужен пользовательский string name, чтобы установить возможность и получить ее значение. - person frianH; 05.08.2019
comment
@Frian Проверьте обновление ответа и дайте мне знать о статусе. - person DebanjanB; 05.08.2019
comment
я обновил свой вопрос с дополнительным объяснением, может быть, у вас есть идеи. - person frianH; 08.08.2019
comment
@Frian testName не является стандартной возможностью. Вы не можете отправить его в RemoteWebDriver. - person DebanjanB; 08.08.2019

Похоже, что вы ищете, как добавить пользовательскую возможность в вашу конфигурацию Grid. Это возможно, но требует нескольких шагов.

Во-первых, вам нужно создать средство сопоставления возможностей. Сопоставитель будет отдельным проектом, импортирующим библиотеки Selenium-Server и Selenium-Java в качестве зависимостей. Вам понадобится один класс, который расширяет org.openqa.grid.internal.utils.DefaultCapabilityMatcher и переопределяет метод matches() вашей собственной логикой, чтобы определить, обладает ли узел желаемой возможностью. По завершении вы соберете этот проект и сгенерируете jar-файл.

Во-вторых, вам нужно будет подключить новый сопоставитель к Grid Hub. Я храню свои jar-файлы сопоставления в том же каталоге, что и мой selenium-server-standalone jar, и я изменяю свою обычную команду запуска, чтобы приспособить сопоставление.

java -cp <custom-matcher>-1.0.0.jar;selenium-server-standalone-3.141.59.jar org.openqa.grid.selenium.GridLauncher -role hub -hubConfig hubConfig.json

В моем hubConfig.json мне пришлось добавить две строки в JSON, чтобы подключить сопоставитель:

  "capabilityMatcher": "fully.qualified.path.to.Matcher",
  "throwOnCapabilityNotPresent": true,

В-третьих, вам нужно будет настроить свои узлы, чтобы принять новую возможность. Если вы также используете JSON для настройки своих узлов, это так же просто, как добавить новую строку для вашей возможности:

"capabilityName": "foo"

Вот и все. Также стоит отметить, что DesiredCapabilities имеет возможность, называемую applicationName, которая остается определяемым пользователем значением. В зависимости от вашего конкретного варианта использования вы можете использовать эту возможность вместо добавления чего-то нового.

Недавно я нашел образец репозитория на Github, когда сам изучал этот процесс. Это базовая установка, но она довольно хорошо иллюстрирует описанные выше шаги. Это должно дать вам отличную отправную точку для вашей собственной реализации.

person tim-slifer    schedule 09.08.2019
comment
Позвольте мне проверить, я вернусь к вам. - person frianH; 09.08.2019
comment
извините за поздний ответ, спасибо за предложение. Я выполнил шаги, как вы предлагаете, достаточно долго на первом этапе :), но вы можете исправить мою работу? неправильно или верно с вашим обзором. Концентратор и узел работают нормально, обозначьте 10:29:44.122 INFO [SelfRegisteringRemote.registerToHub] - The node is registered to the hub and ready to use. - person frianH; 15.08.2019
comment
Это значение custom-capability.jar : public class CustomCapability extends DefaultCapabilityMatcher { private final String testName = "testName"; boolean allCapabilitiesAvailability = false; - person frianH; 15.08.2019
comment
Это значение hubConfig.json : { "port": 4444, "newSessionWaitTimeout": -1, "servlets" : [], "withoutServlets": [], "custom": {}, "capabilityMatcher": "com.matcher.CustomCapability", "throwOnCapabilityNotPresent": true, "cleanUpCycle": 5000, "role": "hub", "debug": false, "browserTimeout": 0, "timeout": 1800 } - person frianH; 15.08.2019
comment
Итак, запустите концентратор с помощью этой команды: java -cp custom-capability.jar:selenium-server-standalone-3.141.59.jar org.openqa.grid.selenium.GridLauncherV3 -role hub -hubConfig hubConfig.json - person frianH; 15.08.2019
comment
Это значение nodeConfig.json : { "capabilities": [ { "browserName": "firefox", "maxInstances": 5, "seleniumProtocol": "WebDriver", "testName": "untitled" }, { "browserName": "chrome", "maxInstances": 5, "seleniumProtocol": "WebDriver", "testName": "untitled" } ], "proxy": "org.openqa.grid.selenium.proxy.DefaultRemoteProxy", "maxSession": 5, "port": 5555, "register": true, "registerCycle": 5000, "hub": "http://localhost:4444" - person frianH; 15.08.2019
comment
Итак, запустите узел с помощью этой команды: java -Dwebdriver.chrome.driver=chromedriver -Dwebdriver.gecko.driver=geckodriver -cp custom-capability.jar:selenium-server-standalone-3.141.59.jar org.openqa.grid.selenium.GridLauncherV3 -role node -nodeConfig nodeConfig.json - person frianH; 15.08.2019
comment
Мой вопрос в том, что код тестового сценария, подобный этому вопросу, который я пробовал, устанавливает dc.setCapability("testName", "untitled");, это отличная работа, но если я использую эту команду: driver.getCapabilities().getCapability("testName"), она возвращает null. Затем я попытался установить dc.setCapability("testName", "login");, он получает такую ​​​​ошибку: org.openqa.selenium.WebDriverException: Error forwarding the new session cannot find : Capabilities {browserName: chrome, testName: login} - person frianH; 15.08.2019
comment
Действительно ли результаты вашего предложения привели к этому? если нет, то где моя ошибка? Поскольку суть моего вопроса в том, как testName можно сделать параметром, его можно заполнить любым значением string, и я могу получить значение testName с помощью этого: driver.getCapabilities().getCapability("testName"), спасибо и, пожалуйста, помогите мне еще раз для обзора :) - person frianH; 15.08.2019
comment
На первый взгляд, я думаю, что команду запуска для ваших узлов, возможно, придется изменить. Я бы начал с удаления аргументов -Dwebdriver. Также, по-видимому, сейчас существует известная проблема с сопоставлениями возможностей, но существуют обходные пути. См. это на Github. - person tim-slifer; 19.08.2019
comment
Я пойду по ссылке и выясню, кстати, с правильным результатом, могу ли я изменить значение testName с любой строкой, как я имею в виду? пример : dc.setCapability("testName", "login"); - person frianH; 21.08.2019
comment
dc.setCapability() не предназначено для присвоения нового значения. Matcher и конфигурация JSON определяют набор возможностей, которыми обладает Node (например, какой браузер, какая ОС и т. д.). В случае пользовательских возможностей (таких как ваша опция testName) вы назначите значение каждому узлу в конфигурации JSON. Затем, при настройке вашего экземпляра DesiredCapabilities для передачи вашему RemoteWebDriver, вы сообщаете DC, какие возможности искать при выборе узла для запуска теста. - person tim-slifer; 26.08.2019
comment
Вызывая setCapability(), вы сообщаете DC, какие из опций использовать, которые вы назначили своим различным узлам. В вашем примере dc.setCapability("testName", "login") вы указываете DC найти узел со значением "login" для возможности "testName". - person tim-slifer; 26.08.2019