dequelabs / axe-core-gems

Ruby integration for axe-core, the accessibility testing engine
https://deque.com/axe
Mozilla Public License 2.0
90 stars 30 forks source link

Release 4.3 introduces breaking change for `:cuprite` driver #243

Open khiga8 opened 2 years ago

khiga8 commented 2 years ago

Hi team,

We are trying to upgrade our axe-core-api version from 4.2 to 4.4.1. Here is the related PR.

However, we're blocked due to this new error that emerges:

undefined method `execute_script' for #<Capybara::Cuprite::Browser:0x00005646aaca3770>

I've ran into the same error when bumping to 4.3 and traced it down to this PR: https://github.com/dequelabs/axe-core-gems/pull/199 which introduces some changes related to ExecEvalScriptAdapter2.

Stack trace:

NoMethodError: undefined method `execute_script' for #<Capybara::Cuprite::Browser:0x00005646aaca3770>
    /workspaces/view_components/vendor/bundle/ruby/2.7.0/gems/axe-core-api-4.3.2/lib/webdriver_script_adapter/exec_eval_script_adapter.rb:35:in `execute_script_fixed'

Any advice for how we can resolve this? We use the :cuprite driver. We don't have any issues using :cuprite with versions before 4.3.

uday708 commented 2 years ago

I am also getting undefined method execute_script for #<Capybara::Poltergeist::Browser:0x4be8d40e> error with axe-core-rspec v4.0.0, can someone help me here for any solution. @khiga8

nialbima commented 2 years ago

I'm having this issue when migrating our system specs to Cuprite. From what I can tell, it's because this method changes the page target to page.driver.browser, which is a Capybara::Cuprite::Browser object:

      def get_selenium(page)
        page = page.driver if page.respond_to?("driver")
        page = page.browser if page.respond_to?("browser") and not page.browser.is_a?(::Symbol)
        page
      end

Doing something gross like monkey-patching the method in doesn't fix the issue. That leads to some other weirdness, and I've now lost a full day to poking at this and need to abandon this migration. If anybody has any tips, I'm ten-thousand-percent ears.

khiga8 commented 2 years ago

@uday708 and @nialbima, I never resolved this issue.

I've now lost a full day to poking at this and need to abandon this migration

This happened to me too. I thought it could be a simple update but it didn't turn out that way...

I followed up with the axe team on their Slack group and they mentioned that their code now assumes the driver is selenium, and that adding cuprite support might involve a new package altogether. I've put aside this migration effort for now since our team is considering a move away from cuprite, but perhaps you can follow up with them.

Here's the Slack message in the axe community slack group.

nialbima commented 2 years ago

@khiga8 Thanks for the link! At this point, it seems like I'm going to be yelling at Selenium for the rest of my career 🙃. If you guys wind up deciding to stick with Cuprite and developing a new gem, I'd be open to contributing.

camertron commented 2 years ago

I looked into this today and was able to get things working via these three monkeypatches:

module Capybara
  class Session
    alias_method :execute_async_script, :evaluate_async_script
  end

  module Cuprite
    class Browser
      alias_method :execute_async_script, :evaluate_async
    end
  end
end

module Ferrum
  class Frame
    module Runtime
      prepend Module.new {
        def evaluate_async(expression, *args)
          # second argument is a timeout in milliseconds
          super(expression, 10 * 1000, *args)
        end
      }
    end
  end
end

To be clear: I don't think anyone should actually use these, but I thought I'd comment here for posterity and in case it helps with any future work.

adam-h commented 5 months ago

Sadly this now fails in more places with latest axe-core-rspec (4.9.0) and cuprite (0.15.1).

I tried extending @camertron's patch to provide the browser.manage.timeouts.page_load getter/setter and the browser.execute_script method but hit a JS syntax error from Ferrum:

Ferrum::JavaScriptError:
       SyntaxError: Unexpected token 'const'

It's not working, but here's the patch I used to get this far:

module Capybara
  class Session
    alias_method :execute_async_script, :evaluate_async_script
  end

  module Cuprite
    class Browser
      alias_method :execute_async_script, :evaluate_async
      alias_method :execute_script, :evaluate

      def manage
        @manage ||= FakeManager.new(self)
      end

      class FakeManager
        def initialize(browser)
          @browser = browser
        end

        def timeouts
          @timeouts ||= FakeTimeouts.new(@browser)
        end
      end

      class FakeTimeouts
        def initialize(browser)
          @browser = browser
        end

        def page_load
          @browser.timeout
        end

        def page_load=(t)
          @browser.timeout = t
        end
      end
    end
  end
end

module Ferrum
  class Frame
    module Runtime
      prepend Module.new {
        def evaluate_async(expression, *args)
          # second argument is a timeout in milliseconds
          super(expression, 10 * 1000, *args)
        end
      }
    end
  end
end
rickychilcott commented 4 months ago

Just wondering if cuprite is intended to be supported by this gem?

We are just starting to use axe in one of our apps -- and this is the only one we use cuprite with.

ohrite commented 3 months ago

I got the axe matcher at least running in my suite without raising using the following gist, but I'm not getting the error reporting I'd expect: https://gist.github.com/ohrite/242f6babdc346462c6e5e34e6d3a7f89