So this is kind of last minute, but I thought it would be interesting to try and create a bug report template for Action Cable.
After having wasted maybe an hour or so trying to parse the browser logs, only to realize that Chrome prepends the file/url and line number before simply [object Object]
style -- I ended up just writing to a <textarea>
the data from the websocket. I think this is a step in the right direction though, and it was a fun experiment at least.
Here it is.
# frozen_string_literal: true
require "bundler/inline"
gemfile(true) do
source "https://rubygems.org"
git_source(:github) { |repo| "https://github.com/#{repo}.git" }
gem "rails", github: "rails/rails", branch: "main"
# system test dependencies
gem "puma"
gem "capybara"
gem "selenium-webdriver"
end
require "action_controller/railtie"
require "action_cable/engine"
class TestApp < Rails::Application
#config.load_defaults Rails::VERSION::STRING.to_f
config.root = __dir__
config.eager_load = false
config.logger = Logger.new($stdout)
Rails.logger = config.logger
config.action_cable.cable = { "adapter" => "async" }
routes.append do
get "/test" => "test#index"
get "/broadcast" => "test#broadcast"
end
end
class TestController < ActionController::Base
include Rails.application.routes.url_helpers
def index
render inline: DATA.read
end
def broadcast
ActionCable.server.broadcast "test_channel", { message: "hello" }
render plain: "ok"
end
end
class TestChannel < ActionCable::Channel::Base
def subscribed
stream_from "test_channel"
end
end
Rails.application.initialize!
require "minitest/autorun"
class BugTest < ActionDispatch::SystemTestCase
driven_by :selenium, using: :chrome do |driver_options|
driver_options.logging_prefs = { browser: "ALL" }
driver_options.add_argument("--headless=new")
end
test "sends logs from the server" do
# page.driver.browser.logs.get(:browser)
visit "/test"
click_button "Broadcast"
logs = find("#log")
assert_equal '{"message":"hello"}', logs.value
end
end
__END__
<html>
<head>
<script type="importmap">
{
"imports": {
"@rails/actioncable": "https://jspm.dev/@rails/actioncable"
}
}
</script>
<script type="module">
import * as ActionCable from "@rails/actioncable"
ActionCable.logger.enabled = true
const consumer = ActionCable.createConsumer()
consumer.subscriptions.create("TestChannel", {
received(data) {
document.getElementById("log").value = JSON.stringify(data)
}
})
</script>
</head>
<body>
<button onclick="fetch('/broadcast')">Broadcast</button>
<textarea id="log"></textarea>
</body>
</html>