Skip to content

Instantly share code, notes, and snippets.

@carlosantoniodasilva
Last active February 18, 2020 00:38
Show Gist options
  • Save carlosantoniodasilva/171002ec38d2700c17060d221638bc47 to your computer and use it in GitHub Desktop.
Save carlosantoniodasilva/171002ec38d2700c17060d221638bc47 to your computer and use it in GitHub Desktop.
Sample one-file app to try to reproduce an issue with Capybara + Apparition: https://github.com/twalpole/apparition/issues/40
# frozen_string_literal: true
=begin
Sample one-file app to try to reproduce an issue with Capybara + Apparition:
https://github.com/twalpole/apparition/issues/40
Running the file using `ruby` causes it to fail and log the following response:
log: -> RESPONSE: "" "success" {"readyState":4,"responseText":"","status":200,"statusText":"OK"}
As long as the server or the client try to set the type to JSON it seems to get the above result.
Trying to change the client/server to talk via "text" instead, and we get:
log: -> RESPONSE: "Extra Content" "success" {"readyState":4,"responseText":"Extra Content","status":200,"statusText":"OK"}
Showing the expected response coming from the server, and the test pass that way.
The same test runs green with poltergeist/phantomjs, with the following response being logged:
-> RESPONSE: {"content":"Extra Content"} "success" {"readyState":4,"responseText":"{\"content\":\"Extra Content\"}","responseJSON":{"content":"Extra Content"},"status":200,"statusText":"OK "}
=end
# To run with a different driver, e.g. poltergeist, use `DRIVER=poltergeist ruby...`
DRIVER = ENV["DRIVER"] || "apparition"
require "bundler/inline"
gemfile(true) do
source "https://rubygems.org"
git_source(:github) { |repo| "https://github.com/#{repo}.git" }
gem "railties"
gem "actionpack"
gem "capybara"
gem DRIVER
end
require "rack/test"
require "action_controller/railtie"
TEMPLATE = <<~EOF.html_safe
<html>
<head>
<title>Capybara + Apparition Bug Repro</title>
<script src="https://code.jquery.com/jquery-3.4.1.min.js" integrity="sha256-CSXorXvZcTkaix6Yvo6HppcZGetbYMGWSFlBw8HfCJo=" crossorigin="anonymous"></script>
<script>
$(function() {
console.log("-> LOADED");
$("[data-click]").on("click", function() {
console.log("-> REQUEST");
$.ajax({
method: "GET",
url: "/extra",
// Adding the dataType doesn't seem to work either, only if both client & server agree on "text".
// dataType: "json",
success: function(extra, textStatus, jqXHR) {
console.log("-> RESPONSE: ", JSON.stringify(extra), JSON.stringify(textStatus), JSON.stringify(jqXHR));
// To double check the test, it should pass by manually adding the content here.
// $("[data-extra]").text("Extra Content");
$("[data-extra]").text(JSON.stringify(extra));
}
});
});
});
</script>
</head>
<body>
<a data-click>Hello World!</a>
<p data-extra></p>
</body>
</html>
EOF
class TestApp < Rails::Application
config.root = __dir__
config.hosts << "example.org"
config.session_store :cookie_store, key: "cookie_store_key"
secrets.secret_key_base = "secret_key_base"
config.logger = Logger.new($stdout)
Rails.logger = config.logger
routes.draw do
get "/" => "test#index"
get "/extra" => "test#extra"
end
end
require "capybara/rails"
require "capybara/#{DRIVER}"
Capybara.default_driver = DRIVER.to_sym
Capybara.server = :webrick
class TestController < ActionController::Base
include Rails.application.routes.url_helpers
def index
render html: TEMPLATE
end
def extra
puts "-> EXTRA"
render json: { content: "Extra Content" }
# Rendering plain text back and not using `dataType` (or setting it to `text`) appears to work.
# render plain: "Extra Content"
end
end
require "minitest/autorun"
class BugTest < Minitest::Test
include Capybara::DSL
def teardown
super
Capybara.reset_sessions!
Capybara.use_default_driver
end
def test_returns_success
visit "/"
assert page.has_content?("Hello World!")
assert page.has_no_content?("Extra Content")
find("[data-click]").click
assert page.has_content?("Extra Content")
end
private
def app
Rails.application
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment