После обновления Chrome в тестах автоматизации Cucumber Ruby появляется сообщение "Невозможно вызвать не стандартную команду W3C"

У нас есть фреймворк автоматизации Cucumber Ruby, в котором мы проводим несколько тестов на браузере Chrome без головы в Docker на Jenkins. Несколько дней назад мы начали получать сообщение об ошибке "Эта версия ChromeDriver поддерживает только Chrome версии 75", на этот раз мы использовали ChromeDriver 2.46 и браузер google-chrome-unstable с помощью следующей команды:

#Chrome
RUN wget -q -O - https://dl-ssl.google.com/linux/linux_signing_key.pub | apt-key add -
RUN echo "deb http://dl.google.com/linux/chrome/deb/ stable main" >> /etc/apt/sources.list.d/google.list
RUN apt-get update -y
RUN apt-get install -y google-chrome-unstable
RUN apt-get install unzip

# Set up Chromedriver Environment variables
ENV CHROMEDRIVER_VERSION 2.46
ENV CHROMEDRIVER_VERSION 75.0.3770.8
ENV CHROMEDRIVER_DIR /chromedriver
RUN mkdir $CHROMEDRIVER_DIR
# Download and install Chromedriver
RUN wget -q --continue -P $CHROMEDRIVER_DIR "http://chromedriver.storage.googleapis.com/$CHROMEDRIVER_VERSION/chromedriver_linux64.zip"
RUN unzip $CHROMEDRIVER_DIR/chromedriver* -d $CHROMEDRIVER_DIR
ENV PATH $CHROMEDRIVER_DIR:$PATH

Сейчас я обновил версию chromedriver до 75.0.3770.8 и браузер для google-chrome-beta=75.0.3770.27-1

#Chrome
RUN wget -q -O - https://dl-ssl.google.com/linux/linux_signing_key.pub | apt-key add -
RUN echo "deb http://dl.google.com/linux/chrome/deb/ stable main" >> /etc/apt/sources.list.d/google.list
RUN apt-get update -y
RUN apt-get install -y google-chrome-beta=75.0.3770.27-1
RUN apt-get install unzip

# Set up Chromedriver Environment variables
ENV CHROMEDRIVER_VERSION 75.0.3770.8
ENV CHROMEDRIVER_DIR /chromedriver
RUN mkdir $CHROMEDRIVER_DIR
RUN echo $CHROMEDRIVER_DIR
# Download and install Chromedriver
RUN wget -q --continue -P $CHROMEDRIVER_DIR "http://chromedriver.storage.googleapis.com/$CHROMEDRIVER_VERSION/chromedriver_linux64.zip"
RUN unzip $CHROMEDRIVER_DIR/chromedriver* -d $CHROMEDRIVER_DIR
ENV PATH $CHROMEDRIVER_DIR:$PATH

И теперь я вижу unknown command: Cannot call non W3C standard command while in W3C mode (Selenium::WebDriver::Error::UnknownCommandError) ошибка.

Можно ли отключить режим W3C или загрузить старую версию браузера Chrome и драйвер, который его не использует? Я думаю, что возможность отключить проверку W3C было бы здорово.

8 ответов

Все, что вам нужно сделать, это просто отключить W3C при инициализации веб-драйвера

options = webdriver.ChromeOptions()
options.add_experimental_option('w3c', False)
create_webdriver('Chrome', options=options)

Окружающая обстановка:

  • Chrome 75
  • ChromeDriver 75

Это сообщение об ошибке...

unknown command: Cannot call non W3C standard command while in W3C mode (Selenium::WebDriver::Error::UnknownCommandError)

... подразумевает, что ChromeDriver не смог вызвать стандартную команду, отличную от W3C, в то время как в режиме W3C инициировал / порождал новый WebBrowser, то есть сеанс браузера Chrome.

Здесь основная проблема заключается в том, что когда клиент ChromeDriver запрашивает W3C-совместимый сеанс, но ответ от ChromeDriver не соответствует спецификации W3C и вызывает ошибки в языковых API.


Анализ

Согласно обсуждению, ответ ChromeDriver в режиме W3C не соответствует стандарту. Джон Чен (владелец - WebDriver для Google Chrome) отметил, что Саймон Стюарт (Creator - WebDriver) обновил, что:

  • Новый ответ сеанса для сеанса w3c должен выглядеть следующим образом:

    {
      "value": {
        "sessionId": "some-uuid",
        "capabilities": {
          "browserName": "chrome",
          ...
        }
      }
    }
    
  • Но при запуске нового сеанса с w3c опция установлена ​​в true в chromeOptions следующим образом:

    • Селен /Python:

      from selenium import webdriver
      opt = webdriver.ChromeOptions()
      opt.add_experimental_option('w3c', True)
      driver = webdriver.Chrome(chrome_options=opt)
      
    • Селен /Java:

      {
        "sessionId": "af4656c27fb94485b7872e1fc616923a",
        "status": "ok",
        "value": {
          "browserName": "chrome",
          ...
        }
      }
      
  • Возвращенный ответ выглядит так:

    {
      "sessionId": "af4656c27fb94485b7872e1fc616923a",
      "status": "ok",
      "value": {
        "browserName": "chrome",
        ...
      }
    }
    

Это не является ни правильно сформированным ответом для протокола JSON Wire (где "status" будет целое число), ни правильно сформированным ответом W3C, и без правильно сформированного ответа нельзя использовать w3c-совместимый.

Этот пересмотр и эта фиксация решают эту проблему.


Этот случай использования

Поскольку вы используете ChromeDriver v75.x и Chrome v75.x, и вы все еще видите ту же ошибку, вам нужно пройти ExperimentalOption w3c как true исключительно так:

capabilities = { "chromeOptions" => {'w3c' => true} }

Обновить

До ChromeDriver v74.x, Chrome и ChromDriver по умолчанию работали в режиме w3c, но в chromedriver / server / http_handler.cc была ошибка. Согласно сведениям в goog:chromeOptions.w3c=false не работает для запроса POST с пустым телом:

метод HttpHandler::HandleCommand проверяет значение kW3CDefault константа вместо сессии goog:chromeOptions.w3c стоимость. В результате была нарушена поддержка протокола JSON Wire, где разрешены запросы POST с пустым телом. Протокол JSON Wire будет востребован до displayed конечная точка возобновляется в режиме w3c. Следует отметить, что спецификация W3C WebDriver не запрещает использование "отображаемой" конечной точки, и эта функция активно используется в некоторых API.

Как Is Element Displayed Команда не является частью спецификации W3C, но все еще используется некоторыми API, и ее функциональность может быть трудно воспроизвести в этих API. Этот список изменений [ revision and commit ] повторно включает эту команду в режиме W3C, чтобы облегчить переход в режим W3C.

@John уже подтвердил, что мы ожидаем обновления ChromeDriver v75.0 завтра с исправлением.


Вот решение

Как и обещал Джон Чен [Владелец - WebDriver для Google Chrome], версии ChromeDriver 75.0.3770.90 и 76.0.3809.25 были выпущены и теперь доступны на сайте загрузок ChromeDriver. Эти версии включают следующие исправления ошибок в предыдущих выпусках ChromeDriver 75 и 76:

  • Исправлена ​​ошибка, из-за которой некорректно отклонялись POST-запросы с пустым телом в режиме OSS
  • Добавлены новые конечные точки для получения журнала Chrome

Кроме того, версия 76.0.3809.25 также включает следующие изменения:

  • Добавлена ​​конечная точка для команды Is Displayed в режиме W3C

снимок

75_76

Если вы получаете эту ошибку, используя rails + rspec + capybara + selenium, способ пропустить опцию отключения W3C выглядит следующим образом:

Capybara.register_driver :chrome do |app|
  capabilities = Selenium::WebDriver::Remote::Capabilities.chrome(
    chromeOptions: {'w3c' => false}
  )
  Capybara::Selenium::Driver.new(app, :browser => :chrome, desired_capabilities: capabilities)
end

Просто добавьте w3c: false в конце, как в этом примере:

  capabilities = Selenium::WebDriver::Remote::Capabilities.chrome(chromeOptions: { args: ["window-size=#{DEFAULT_X_RES},#{DEFAULT_Y_RES}"], w3c: false })

Для моих друзей по PHP, которые ищут глубины интернета...
Новейшая версия PHPUnit_Extensions_Selenium2TestCase

Который на данный момент является композиторским ограничением

"phpunit/phpunit-selenium": ">=7",
"phpunit/phpunit": ">=6" 

Можно использовать следующие параметры. Обратите внимание на мою борьбу::

'w3c' => ложь

Это должно быть логическое значение, а не строка.

class NavigationTest extends PHPUnit_Extensions_Selenium2TestCase
{

    public function setUp()
    {
        static $count;
        $count or $count = 1 and print PHP_EOL . 'java -jar ' . dirname(__DIR__) . '/selenium-server-standalone-3.141.59.jar' . PHP_EOL;
        self::shareSession(true);
        $this->setDesiredCapabilities([
            "chromeOptions" => [
                'w3c' => false
            ]
        ]);
        $this->setHost('localhost');
        $this->setPort(4444);
        $this->setBrowser('chrome');
        $this->setBrowserUrl('http://localhost:9919/');
        $this->prepareSession()->currentWindow()->maximize();

    }
}

Не уверен, какую платформу вы используете, но у меня такая же ошибка после обновления моего браузера и chromedriver до последней версии v75.0.3770.90. Мое предложение состоит в том, чтобы найти раздел инициализации сеанса в ваших сценариях и добавить опцию, чтобы отключить w3c, Например, мой перед обновлением:

chrome_options = Selenium::WebDriver::Chrome::Options.new
options[:options] = chrome_options
Capybara::Selenium::Driver.new(app, options)

после обновления

chrome_options = Selenium::WebDriver::Chrome::Options.new
chrome_options.add_option('w3c',false)
options[:options] = chrome_options
Capybara::Selenium::Driver.new(app, options)

В моем случае это была другая версия selenium, которая не поддерживала w3c. Уменьшите chromedriver до версии 74.0.3729.6, чтобы все работало. Это также можно исправить, обновив версию Selen до последней, поддерживающей W3C.

Пожалуйста, начните читать документацию вместо того, чтобы «просто отключать» то, что есть по какой-то причине.

Например, выполнение скриптов:

  • /session/{идентификатор сеанса}/execute/sync
  • /session/{идентификатор сеанса}/execute/асинхронный
Другие вопросы по тегам