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

System specs CI exploration #637

Draft
wants to merge 10 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions .github/workflows/backend.yml
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ jobs:
POSTGRES_PORT: 5432
INTERCOM_SECRET: secret
BASE_URL: test.com
NODE_VERSION: 12.22.6

services:
redis:
Expand All @@ -111,6 +112,16 @@ jobs:

steps:
- uses: actions/checkout@v2.3.4
- uses: actions/setup-node@v2
with:
node-version: ${{ env.NODE_VERSION }}
cache: npm
cache-dependency-path: frontend/package-lock.json

- name: Setup node
run: npm install -g npm@7.0.0
working-directory: ./frontend
- run: npm install

- name: Install PostgreSQL client
run: |
Expand Down
2 changes: 2 additions & 0 deletions backend/Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,8 @@ group :development do
end

group :test do
gem "capybara"
gem "cuprite"
gem "mongoid-rspec"
gem "shoulda-matchers"
gem "vcr"
Expand Down
23 changes: 23 additions & 0 deletions backend/Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,15 @@ GEM
cancancan (3.3.0)
cancancan-mongoid (2.0.0)
cancancan (>= 2.0, < 4)
capybara (3.39.2)
addressable
matrix
mini_mime (>= 0.1.3)
nokogiri (~> 1.8)
rack (>= 1.6.0)
rack-test (>= 0.6.3)
regexp_parser (>= 1.5, < 3.0)
xpath (~> 3.2)
coderay (1.1.3)
coercible (1.0.0)
descendants_tracker (~> 0.0.1)
Expand All @@ -109,6 +118,9 @@ GEM
crack (0.4.5)
rexml
crass (1.0.6)
cuprite (0.14.3)
capybara (~> 3.0)
ferrum (~> 0.13.0)
database_cleaner (2.0.2)
database_cleaner-active_record (>= 2, < 3)
database_cleaner-active_record (2.1.0)
Expand Down Expand Up @@ -170,6 +182,11 @@ GEM
faraday-net_http_persistent (1.2.0)
faraday-patron (1.0.0)
faraday-rack (1.0.0)
ferrum (0.13)
addressable (~> 2.5)
concurrent-ruby (~> 1.1)
webrick (~> 1.7)
websocket-driver (>= 0.6, < 0.8)
ffaker (2.21.0)
ffi (1.15.5-java)
forecast_io (2.0.2)
Expand Down Expand Up @@ -213,6 +230,7 @@ GEM
net-pop
net-smtp
marcel (1.0.2)
matrix (0.4.2)
method_source (1.0.0)
mini_mime (1.1.2)
mini_portile2 (2.8.4)
Expand Down Expand Up @@ -446,11 +464,14 @@ GEM
addressable (>= 2.8.0)
crack (>= 0.3.2)
hashdiff (>= 0.4.0, < 2.0.0)
webrick (1.8.1)
websocket-driver (0.7.6)
websocket-extensions (>= 0.1.0)
websocket-driver (0.7.6-java)
websocket-extensions (>= 0.1.0)
websocket-extensions (0.1.5)
xpath (3.2.0)
nokogiri (~> 1.8)
yard (0.9.34)
zeitwerk (2.6.9)

Expand All @@ -471,8 +492,10 @@ DEPENDENCIES
byebug
cancancan (~> 3.3.0)
cancancan-mongoid (= 2.0.0)
capybara
colored (~> 1.2)
countries
cuprite
database_cleaner
database_cleaner-mongoid
devise (= 4.8.0)
Expand Down
7 changes: 7 additions & 0 deletions backend/env-example
Original file line number Diff line number Diff line change
Expand Up @@ -55,3 +55,10 @@ FULLSTORY_ORG=

# MongoDB
MONGODB_HOST=localhost

# System spec server ports
SYSTEM_SPEC_BACKEND_PORT=3003
SYSTEM_SPEC_FRONTEND_PORT=4303

# Run system specs with a headless chrome instance
HEADLESS_CHROME=true
17 changes: 17 additions & 0 deletions backend/lib/tasks/spec.rake
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
require_relative "../../spec/system/support/frontend_app"

namespace :spec do
namespace :system do
task :start_frontend do
frontend_app = SystemSpec::FrontendApp.instance
frontend_app.start $stdout

trap "INT" do
frontend_app.stop
exit 1
end

frontend_app.wait_on
end
end
end
8 changes: 8 additions & 0 deletions backend/spec/system/signup_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
require "system_spec_helper"

RSpec.describe "signup flow" do
it "loads the root page" do
visit "/"
expect(page.title).to eq "Flaredown"
end
end
19 changes: 19 additions & 0 deletions backend/spec/system/support/capybara_config.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# Usually, especially when using Selenium, developers tend to increase the max wait time.
# With Cuprite, there is no need for that.
# We use a Capybara default value here explicitly.
Capybara.default_max_wait_time = 2

# Normalize whitespaces when using `has_text?` and similar matchers,
# i.e., ignore newlines, trailing spaces, etc.
# That makes tests less dependent on slightly UI changes.
Capybara.default_normalize_ws = true

# Where to store system tests artifacts (e.g. screenshots, downloaded files, etc.).
# It could be useful to be able to configure this path from the outside (e.g., on CI).
Capybara.save_path = ENV.fetch("CAPYBARA_ARTIFACTS", "./tmp/capybara")

# Port on which to fire up the rails backend.
Capybara.server_port = ENV["SYSTEM_SPEC_BACKEND_PORT"]

# Where to find frontend app; see ./frontend_app.rb
Capybara.app_host = "http://localhost:#{ENV["SYSTEM_SPEC_FRONTEND_PORT"]}"
20 changes: 20 additions & 0 deletions backend/spec/system/support/cuprite_config.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# First, load Cuprite Capybara integration
require "capybara/cuprite"

# Then, we need to register our driver to be able to use it later
# with #driven_by method.
# NOTE: The name :cuprite is already registered by Rails.
# See https://github.com/rubycdp/cuprite/issues/180
Capybara.register_driver(:better_cuprite) do |app|
Capybara::Cuprite::Driver.new(
app,
window_size: [1200, 800],
browser_options: {},
process_timeout: 10,
inspector: true,
headless: ENV["HEADLESS_CHROME"] != "false"
)
end

# Configure Capybara to use :better_cuprite driver by default
Capybara.default_driver = Capybara.javascript_driver = :better_cuprite
79 changes: 79 additions & 0 deletions backend/spec/system/support/frontend_app.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
module SystemSpec
class FrontendApp
include Singleton

def start(log = "/dev/null")
if test_connection_to_frontend_app
puts "Frontend app already running at #{frontend_app_url}"
return
end

puts "Starting frontend app at #{frontend_app_url}"
puts `pwd`
puts "ls .."
puts `ls ..`
puts "ls ../frontend"
puts `ls ../frontend`
@pid ||= Process.spawn(
frontend_app_cmd,
[:out, :err] => log,
:chdir => "../frontend"
)

timeout = 15.seconds
unless test_connection_to_frontend_app(timeout)
fail "Frontend app did not start within #{timeout} seconds"
end
end

def wait_on
return unless @pid
Process.wait @pid
end

def stop
return unless @pid
Process.kill "QUIT", @pid
Process.wait @pid
end

private

def test_connection_to_frontend_app(timeout = 0)
system(
test_connection_cmd(timeout),
out: "/dev/null"
)
end

def test_connection_cmd(timeout)
[
"curl --silent --head -X GET",
"--retry-connrefused",
"--retry", timeout.to_s,
"--retry-delay", "1",
frontend_app_url
].join(" ")
end

def frontend_app_cmd
[
"./node_modules/.bin/ember", "serve",
"--port", frontend_port,
"--proxy", "http://localhost:#{backend_port}"
].join(" ")
end

def frontend_app_url
"http://localhost:#{frontend_port}"
end

def frontend_port
ENV["SYSTEM_SPEC_FRONTEND_PORT"]
end

def backend_port
ENV["SYSTEM_SPEC_BACKEND_PORT"]
end
end
end
21 changes: 21 additions & 0 deletions backend/spec/system_spec_helper.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
require "rails_helper"

# Most of the system spec config was borrowed, with many thanks, from:
# https://evilmartians.com/chronicles/system-of-a-test-setting-up-end-to-end-rails-testing
require "system/support/frontend_app"
require "system/support/capybara_config"
require "system/support/cuprite_config"

RSpec.configure do |config|
config.prepend_before(:each, type: :system) do
driven_by Capybara.javascript_driver
end

config.before(:suite) do
SystemSpec::FrontendApp.instance.start
end

config.after(:suite) do
SystemSpec::FrontendApp.instance.stop
end
end
Loading