2

J'utilise Capybara, la gemme selenium-webdriver, et le driver chromé pour piloter mes tests activés par javascript.Capybara/Selenium obtient un Net :: ReadTimeout aléatoirement sur location.reload()

Le problème est qu'environ 50% de nos builds échouent en raison d'une erreur Net::ReadTimeout. Au début, cela se manifestait par une erreur «could not find element», mais après avoir augmenté le temps d'attente maximum par défaut de Capybara à 30 secondes, j'ai commencé à voir le timeout.

J'ai regardé les captures d'écran du moment où le timeout arrive, il est bloqué sur un modal 'Connexion réussie' que nous montrons brièvement avant d'utiliser la fonction Javascript, location.reload(), pour recharger la page.

J'ai effectué le test localement et je peux parfois le reproduire, même de façon aléatoire. Parfois, il zips par ce modal et fait le rechargement si vite que vous pouvez à peine le voir, et d'autres fois, il pend juste pour toujours.

Je ne pense pas que ce soit un problème de compilation d'actifs, puisque le site a déjà été chargé à ce moment-là pour que l'utilisateur puisse accéder au formulaire de connexion. Vous vous demandez si quelqu'un a déjà vu cela et connaît une solution.

Le code spécifique:

visit login_path 

    page.within '#sign-in-pane__body' do 
     fill_in 'Email', with: user.email 
     click_button 'Submit' 
    end 

    expect(page).to have_content 'Enter Password' 

    page.within '#sign-in-pane__body' do 
     fill_in 'Password', with: user.password 
     click_button 'Submit' 
    end 

    expect(page).to have_text 'Home page landing text' 

Raccrocher se passe entre click_button 'Submit' et attendre le texte de la page d'accueil. Le flux de la logique entraînant le délai d'expiration est l'utilisateur soumet le formulaire de connexion, nous attendons que le serveur affiche un modèle .js.erb qui déclenche un événement JS lors de la connexion réussie. Lorsque ce déclencheur se produit, nous montrons un modal disant que la connexion a été réussie, puis exécutez un location.reload().

+0

Do vous avez quelque chose dans votre application (rack-attaque, etc) qui étrangle les demandes? Si ce n'est pas le cas, vérifiez votre test.log pour savoir si la requête a bien été faite et ce que l'application faisait. En outre, que définissez-vous comme 'Capybara.server'? –

+0

Je sais que j'ai dit hier que j'étais capable de reproduire localement, mais j'ai du mal à le faire aujourd'hui pour vérifier le journal. Pas de limitation de la demande. Je ne mets pas le serveur manuellement à quoi que ce soit, donc c'est par défaut. –

+1

Si vous n'avez pas défini 'Capybara.server' pour tout ce qui est par défaut Webrick qui peut avoir des problèmes avec plusieurs demandes simultanées. Essayez de configurer 'Capybara.server =: puma' et voyez si cela fait une différence. –

Répondre

0

Il s'est avéré que ce n'était pas exclusif de faire un location.reload() dans JS. Il arrivait parfois juste de visiter une page.

La solution pour moi était de créer un client HTTP pour le pilote de sélénium et spécifier un délai plus:

Capybara.register_driver :chrome do |app| 
    client = Selenium::WebDriver::Remote::Http::Default.new 
    client.read_timeout = 120 

    Capybara::Selenium::Driver.new(app, {browser: :chrome, http_client: client}) 
end 
+0

Cela n'a pas fonctionné pour moi et j'ai continué à obtenir l'erreur –

0

Résolu problème similaire en utilisant ma propre version de la méthode de visite:

def safe_visit(url) 
    max_retries = 3 
    times_retried = 0 
    begin 
    visit url 
    rescue Net::ReadTimeout => error 
    if times_retried < max_retries 
     times_retried += 1 
     puts "Failed to visit #{current_url}, retry #{times_retried}/#{max_retries}" 
     retry 
    else 
     puts error.message 
     puts error.backtrace.inspect 
     exit(1) 
    end 
    end 
end