web-dev-qa-db-fra.com

Impossible d'appeler une commande standard non W3C en mode W3C (Selenium :: WebDriver :: Error :: UnknownCommandError) avec Selenium ChromeDriver dans Cucumber Ruby

Nous avons Cucumber Ruby framework d'automatisation où nous exécutons quelques tests sur Chrome navigateur sans tête dans un Docker sur Jenkins. Il y a quelques jours, nous avons commencé à recevoir une erreur "Ce la version de ChromeDriver ne prend en charge que Chrome version 75 "cette fois, nous utilisions ChromeDriver 2.46 et avec le navigateur google-chrome-unstable à l'aide de la commande suivante:

#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

J'ai maintenant mis à jour la version chromedriver vers 75.0.3770.8 Et le navigateur vers 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

Et maintenant, je peux voir l'erreur comme:

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

Est-il possible de désactiver le mode W3C ou de télécharger une ancienne version de Chrome navigateur et pilote qui ne l'utilise pas? Je pense que la possibilité de désactiver la vérification W3C serait formidable.

14
sugu

Tout ce que vous avez à faire est de désactiver le W3C lors de l'initialisation du pilote Web

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

Environnement:

  • Chrome 75
  • ChromeDriver 75
17

Ce message d'erreur ...

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

... implique que le ChromeDriver n'a pas pu appeler la commande standard non W3C en mode W3C lors du lancement/de la création d'une nouvelle session WebBrowser ie Chrome Browser session.

Ici, le principal problème est, lorsque ChromeDriver le client demande une session compatible W3C mais la réponse de ChromeDriver n'est pas conforme à la spécification W3C et provoque des erreurs dans les API de langue.


Une analyse

Selon la discussion dans la réponse ChromeDriver en mode W3C n'est pas conforme à la norme John Chen (propriétaire - WebDriver pour Google Chrome) mentionné cela, Simon Stewart (créateur - WebDriver) avait mis à jour cette:

  • La nouvelle réponse de session pour une session w3c devrait ressembler à:

    {
      "value": {
        "sessionId": "some-uuid",
        "capabilities": {
          "browserName": "chrome",
          ...
        }
      }
    }
    
  • Mais lors du démarrage d'une nouvelle session avec l'option w3c définie sur true dans les options chromeOptions comme suit:

    • Sélénium/Python:

      from Selenium import webdriver
      opt = webdriver.ChromeOptions()
      opt.add_experimental_option('w3c', True)
      driver = webdriver.Chrome(chrome_options=opt)
      
    • Sélénium/Java:

      {
        "sessionId": "af4656c27fb94485b7872e1fc616923a",
        "status": "ok",
        "value": {
          "browserName": "chrome",
          ...
        }
      }
      
  • La réponse retournée ressemble à:

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

Ce qui n'est ni une réponse correctement formée pour le JSON Wire Protocol (où "status" serait un entier), ni une réponse W3C correctement formée et sans réponse correctement formée, la compatibilité w3c ne peut pas être utilisée.

Cette révision et cette validation ont résolu ce problème.


Ce cas d'utilisation

Comme vous utilisez ChromeDriver v75.x et Chrome v75.x et que vous voyez toujours la même erreur, vous devez passer le ExperimentalOption w3c as true exclusivement comme suit:

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

Mettre à jour

Jusqu'à ChromeDriver v74.x, Chrome et ChromDriver le combo fonctionnait en mode w3c par défaut mais il y avait un bug avec in le chromedriver/server/http_handler.cc . Selon les détails de goog: chromeOptions.w3c = false ne fonctionne pas pour POST avec corps vide :

La méthode HttpHandler::HandleCommand Vérifie la valeur de la constante kW3CDefault Au lieu de la valeur de session goog:chromeOptions.w3c. Par conséquent, la prise en charge du protocole JSON Wire a été interrompue, où POST avec un corps vide sont autorisées. Le protocole JSON Wire sera demandé jusqu'à displayed le point de terminaison est repris en mode w3c. Il convient de noter que la spécification W3C WebDriver n'interdit pas l'utilisation du point de terminaison "affiché" et cette fonctionnalité est activement utilisée dans certaines API.

Comme la commande Is Element Displayed Ne fait pas partie des spécifications du W3C, mais est toujours utilisée par certaines API, et sa fonctionnalité peut être difficile à répliquer dans ces API. Cette Modifier la liste [ révision et commit ] réactive cette commande en mode W3C pour faciliter la transition vers le mode W3C.

@John nous a déjà confirmé s'attendre à une mise à jour de ChromeDriver v75.0 demain avec le correctif.


Voici la solution

Comme promis par John Chen [Propriétaire - WebDriver pour Google Chrome], ChromeDriver versions 75.0.3770.90 et 76.0.3809.25 ont été publiés et sont maintenant disponibles sur le site Téléchargements ChromeDriver . Ces versions incluent les corrections de bogues suivantes par rapport aux versions précédentes de ChromeDriver 75 et 76 :

  • Correction d'un bug qui rejetait incorrectement POST requêtes avec corps vide en mode OSS
  • Ajout de nouveaux points de terminaison pour récupérer Chrome log

De plus, la version 76.0.3809.25 inclut également la modification suivante:

  • Point de terminaison ajouté pour la commande Est affiché en mode W3C

Instantané

75_76

11
DebanjanB

Si vous obtenez cette erreur en utilisant Rails + rspec + capybara + Selenium, la façon de passer l'option pour désactiver le W3C est la suivante:

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
10
mahi-man

Ajoutez simplement w3c: false à la fin comme dans cet exemple:

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

Pour mes PHP amis qui recherchent les profondeurs d'Internet ...
La dernière version de PHPUnit_Extensions_Selenium2TestCase

Ce qui est pour le moment une contrainte composer de

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

Peut utiliser les options suivantes. Notez ma lutte ::

'w3c' => faux

Ce doit être un booléen et non une chaîne.

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();

    }
}
1
Tyler Miles

Je ne sais pas quel framework vous utilisez, mais j'ai la même erreur après la mise à jour de mon navigateur et de chromedriver vers la dernière version v75.0.3770.90. Ma suggestion est de rechercher la section init de session dans vos scripts et d'ajouter l'option pour désactiver w3c. Par exemple, la mienne avant la mise à niveau:

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

après la mise à niveau

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

Dans mon cas, c'était une version différente de Selenium qui ne supportait pas le w3c. Réduisez chromedriver à la version 74.0.3729.6 pour que tout fonctionne. Il pourrait également être corrigé en mettant à jour la version de Selenium vers la dernière version prenant en charge le W3C.

0
SkorpEN