13

J'essaie de passer de PhantomJS à Headless Chrome et j'ai eu des problèmes. Pour les tests locaux, j'utilise Docker Compose pour mettre en service tous les services dépendants. Pour provisionner Google Chrome, j'utilise une image qui regroupe à la fois le ChromeDriver et le tout en le servant sur le port 4444. Je puis lier au mon conteneur d'application comme suit dans ce fichier docker-compose.yml simplifié:"Refus de se connecter" en utilisant ChromeDriver, Capybara & Docker Compose

web: 
    image: web/chrome-headless 
    command: [js-specs] 
    stdin_open: true 
    tty: true 
    environment: 
     - RACK_ENV=test 
     - RAILS_ENV=test 
    links: 
     - "chromedriver:chromedriver" 

chromedriver: 
    image: robcherry/docker-chromedriver:latest 
    ports: 
     - "4444" 
    cap_add: 
     - SYS_ADMIN 
    environment: 
     CHROMEDRIVER_WHITELISTED_IPS: "" 

Ensuite, je dispose d'un fichier spec/spec_helper.rb qui Bootstraps l'environnement de test et de l'outillage associé. Je définis le pilote :headless_chrome et le dirige vers la liaison locale de ChromeDriver; http://chromedriver:4444. Je suis sûr que ce qui suit est correct:

Capybara.javascript_driver = :headless_chrome 

Capybara.register_driver :chrome do |app| 
    Capybara::Selenium::Driver.new(app, browser: :chrome) 
end 

Capybara.register_driver :headless_chrome do |app| 
    capabilities = Selenium::WebDriver::Remote::Capabilities.chrome(
    chromeOptions: { args: %w[headless disable-gpu window-size=1440,900] }, 
) 

Capybara::Selenium::Driver.new app, 
    browser: :chrome, 
    url: "http://chromedriver:4444/", 
    desired_capabilities: capabilities 
end 

Nous utilisons également un magnétoscope, mais je l'ai configuré pour ignorer toutes les connexions au port utilisé par ChromeDriver:

VCR.configure do |c| 
    c.cassette_library_dir = 'spec/vcr_cassettes' 
    c.default_cassette_options = { record: :new_episodes } 
    c.ignore_localhost = true 
    c.allow_http_connections_when_no_cassette = false 
    c.configure_rspec_metadata! 
    c.ignore_hosts 'codeclimate.com' 
    c.hook_into :webmock, :excon 

    c.ignore_request do |request| 
     URI(request.uri).port == 4444 
    end 
end 

Je commence les services avec Docker Compose, qui déclenche le coureur d'essai. La commande est à peu près ceci:

$ bundle exec rspec --format progress --profile --tag 'broken' --tag 'js' --tag '~quarantined' 

Après un peu d'attente, je rencontre le premier test a échoué:

1) Beta parents code redemption: redeeming a code on the dashboard when the parent has reached the code redemption limit does not display an error message for cart codes 
    Failure/Error: fill_in "code", with: "BOOK-CODE" 

    Capybara::ElementNotFound: 
     Unable to find field "code" 
    # ./spec/features/beta_parents_code_redemption_spec.rb:104:in `block (4 levels) in <top (required)>' 

Toutes les spécifications ont la même erreur. Donc, je shell dans le conteneur pour exécuter les tests moi-même manuellement et capturer le HTML sur lequel il teste. Je l'enregistre localement et l'ouvre dans mon navigateur pour être accueilli par la page d'erreur Chrome suivante. Il semblerait que ChromeDriver n'évalue pas le code HTML de la spécification car il ne peut pas l'atteindre. Il tente donc d'exécuter les tests sur cette page d'erreur. Étant donné les informations ci-dessus, qu'est-ce que je fais mal ici? J'apprécie toute l'aide et s'éloigner de PhantomJS résoudrait donc beaucoup de maux de tête pour nous.

Merci beaucoup d'avance. S'il vous plaît, laissez-moi savoir si vous avez besoin d'informations supplémentaires.

enter image description here

+1

Êtes-vous en cours d'exécution RSpec/Capybara sur l'instance de docker ou votre machine locale? Si ce dernier vous devez définir 'Capybara.app_host' pour pointer vers n'importe quelle adresse de votre machine locale à partir de l'instance de docker. –

+0

@ThomasWalpole C'est la première dans ce cas, j'en ai peur. Toutes les choses fonctionnent dans des conteneurs. Merci d'avoir répondu! –

+0

Ah, désolé - j'ai raté le conteneur "web" - réponse venant ci-dessous. –

Répondre

2

Le problème que vous rencontrez est que Capybara, par défaut, commence l'AUT lié à 127.0.0.1 et dit alors le conducteur d'avoir la demande du navigateur de la même. Dans votre cas, 127.0.0.1 n'est pas là où l'application est en cours d'exécution (Du point de vue des navigateurs), car il se trouve sur un autre conteneur que le navigateur. Pour résoudre ce problème, vous devez définir Capybara.server_host à l'interface externe du conteneur "web" (qui est accessible depuis le conteneur "chromedriver"). Cela va amener Capybara à lier l'AUT à cette interface et dire au pilote de demander au navigateur de lui faire des demandes.

Dans votre cas, cela signifie probablement que vous pouvez spécifier 'web'

Capybara.server_host = 'web'