Geb tests pass with Chrome, fail with PhantomJS

2019-06-23 16:22发布

问题:

I have noticed that some Geb functional tests pass with Chrome but fail with PhantomJS, holding all other variables constant. This happens mostly with pages that have some kind of asynchronous activity - one call to $(selector).click() triggers an event handler that updates the DOM, and the DOM updates need to complete before calling $(anotherSelector).click().

I can make the PhantomJS tests pass again by aggressively using waitFor but I don't understand why this would be required with the PhantomJS GhostDriver and not the Chrome driver.

Unfortunately I haven't been able to construct a minimal test case yet isolated from my application.

回答1:

The only advice I can have is to always make sure that any actions in your tests around asynchronous activities are guarded with waitFor statements. You will avoid problems where one driver is quick enough to finish the asynchronous activity before your test tries to access the new/modified element in your page but other isn't. Not using waitFor around asynchronous activities will also bite you when you start running your tests on CI where they are usually slower and you'll see more failures related to asynchronicity in tested pages.

I also wouldn't consider using waitFor to guard every asynchronous activity in your test as being aggressive. You have to remember that waitFor periodically polls the condition and continues as soon as the condition is fulfilled - so if your browser is quick and the page gets updated before waitFor polls for the first time then you're not penalized speed-wise at all but if it's not then you have a guarantee that there will be a retry to see if the asynch action has finished and the condition was fulfilled. What I find aggressive is using ridiculously high timeouts like 30s where they definitely aren't needed - it just means that if your test fail it will take very long time for it to happen.



回答2:

I had a recent experience even with IE and Firefox. This is a list you can try:

  1. Of course, waitFor{}/(timeout: ) is your friend
  2. I am pretty sure Chrome and PhantomJS are not behaving exactly the same way. So, manually try and observe what's the difference, then use something like this:

    if(System.properties["geb.env"]=="chrome") { $(selector).click() } else { // Do something else }