Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How about Capybara-powered checks? #56

Open
Ecco opened this issue Mar 23, 2020 · 1 comment
Open

How about Capybara-powered checks? #56

Ecco opened this issue Mar 23, 2020 · 1 comment

Comments

@Ecco
Copy link

Ecco commented Mar 23, 2020

I've needed to run some rather complex tests on a Nanoc website (involving lots of JS), and the best solution was to use Capybara. It's actually quite nice, and there are just a few gotchas to take care of.

Here's a small gist of the code I wrote:

class ItemCheck < Check
  def browse_to(item)
    @current_item = item
  end

  protected

  def add_issue(desc, subject: nil)
    super(desc, subject: (subject || @current_item.raw_filename))
  end
end

class CapybaraCheck < ItemCheck
  def initialize(context)
    super(context)

    require "adsf"
    require "capybara"
    require "capybara/apparition"
    require "capybara/dsl"

    root = "output"

    Capybara.server = :webrick
    Capybara.default_driver = :apparition
    Capybara.save_path = Pathname.new(__dir__).join("..").realpath
    Capybara.app ||= Rack::Builder.new do
      # use Rack::CommonLogger
      use Rack::ShowExceptions
      use Rack::Lint
      use Rack::Head
      use Adsf::Rack::Caching
      use Adsf::Rack::CORS
      use Adsf::Rack::IndexFileFinder, root: root, index_filenames: %w(index.html)
      run ::Rack::File.new(root)
    end.to_app

    Capybara.reset_sessions!

    CapybaraCheck.include Capybara::DSL
  end

  def browse_to(item)
    super(item)
    visit item.path
  end

  def check_text(text)
    add_issue "Doesn't have #{text.inspect}" unless has_text?(text)
  end

  def check_no_text(text)
    add_issue "Has text #{text.inspect}" unless has_no_text?(text)
  end

  def wait_for_js
    # Obviously we would need something better
    sleep 1
  end
end

And then using it is rather straightforward:

CapybaraCheck.define(:homepage) do
  browse_to @items["/fr/index.html"]
  check_no_text "Foobar"
  click_on "Buy"
  check_text "Free shipping!"
  click_on "Order now"
  add_issue "Wasn't redirected to payment gateway" unless has_current_path?(/mybank.com/, url: true)
end

Question

Would you be interested in adding such a feature within Nanoc directly?

Notes

  • I'm a bit unsatisfied by the adsf part which is copy-pasted from adsf's code (unfortunately getting just the Rack app isn't available (and we'd most likely want to remove the logger anyway).
  • The code does require "capybara" when executing the initialize method. That's kind of weird, but otherwise Capybara would always be loaded alongside nanoc. But I really don't want/need Capybara to be loaded when simply building the site. Anyway, this trick works, but that was painful to write. Maybe checks should live in a separate directory (not /lib) and only be loaded when running them?
@denisdefreyne
Copy link
Member

Capybara is nice! I’ve been using it on other projects as well.

Would you be interested in adding such a feature within Nanoc directly?

I think this would be too far away from Nanoc’s purpose to include within Nanoc itself.

Arguably, even the checks functionality as a whole shouldn’t be part of Nanoc, but rather something independent that Nanoc can easily integrate with. The same goes for the deploy functionality.

I’ll move this issue to the features repository so that the discussion isn’t lost.

@denisdefreyne denisdefreyne transferred this issue from nanoc/nanoc Jun 17, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants