Skip to content

Commit

Permalink
Use Playwright instead of Selenium
Browse files Browse the repository at this point in the history
  • Loading branch information
hulloitskai committed Dec 10, 2023
1 parent edcd0fb commit 4255fd8
Show file tree
Hide file tree
Showing 19 changed files with 13,115 additions and 11,461 deletions.
3 changes: 3 additions & 0 deletions .bashrc
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ export HOMEBREW_PREFIX=/home/linuxbrew/.linuxbrew
# == Nodenv
eval "$(nodenv init -)"

# == Yarn
export PATH="$(yarn global bin):$PATH"

# == Rbenv
eval "$(rbenv init -)"

Expand Down
2 changes: 2 additions & 0 deletions .github/workflows/check.yml
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ jobs:
&& sudo gzip -d /usr/bin/overmind.gz \
&& sudo chmod u+x /usr/bin/overmind \
&& sudo chown $(whoami) /usr/bin/overmind
- name: Install Playwright
run: yarn global add playwright && playwright install
- name: Set up environment
run: bin/setup
- name: Check formatting
Expand Down
21 changes: 12 additions & 9 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,15 @@ RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \
&& sudo apt-get install -yq --no-install-recommends libpq-dev libffi-dev libvips \
&& sudo truncate -s 0 /var/log/*log

# Install Google Chrome
RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \
--mount=type=cache,target=/var/lib/apt,sharing=locked \
curl -sS -o - https://dl-ssl.google.com/linux/linux_signing_key.pub | sudo apt-key add - \
&& sudo touch /etc/apt/sources.list.d/google-chrome.list \
&& sudo echo deb \[arch=amd64\] http://dl.google.com/linux/chrome/deb/ stable main | sudo tee /etc/apt/sources.list.d/google-chrome.list \
&& sudo apt-get -y update -q \
&& sudo apt-get install -yq --no-install-recommends google-chrome-stable \
&& sudo truncate -s 0 /var/log/*log
# # Install Google Chrome
# RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \
# --mount=type=cache,target=/var/lib/apt,sharing=locked \
# curl -sS -o - https://dl-ssl.google.com/linux/linux_signing_key.pub | sudo apt-key add - \
# && sudo touch /etc/apt/sources.list.d/google-chrome.list \
# && sudo echo deb \[arch=amd64\] http://dl.google.com/linux/chrome/deb/ stable main | sudo tee /etc/apt/sources.list.d/google-chrome.list \
# && sudo apt-get -y update -q \
# && sudo apt-get install -yq --no-install-recommends google-chrome-stable \
# && sudo truncate -s 0 /var/log/*log

# Configure shell
RUN mv "$HOME/.bashrc" "$HOME/.bashrc.orig"
Expand All @@ -43,6 +43,9 @@ RUN rbenv install
# Install NodeJS and Yarn
RUN nodenv install && npm install -g yarn

# Install Playwright
RUN yarn global add playwright && playwright install --with-deps

# Install Python and Poetry
RUN pyenv install && pip3 install poetry

Expand Down
9 changes: 5 additions & 4 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -190,9 +190,6 @@ gem "rack-cors", "~> 2.0"
# Load events from Google Calendar
gem "google_calendar", "~> 0.6.4"

# Print resume as PDF with Selenium
gem "selenium-webdriver", "~> 4.11"

# Detect what OS we are running on
gem "os", "~> 1.1"

Expand All @@ -202,9 +199,12 @@ gem "telegram-bot-ruby", "~> 1.0", require: 'telegram/bot'
# Hash passwords with bcrypt
gem "bcrypt", "~> 3.1"

# Compare times
# Compare times with time_difference
gem "time_difference", "~> 0.5.0"

# Control the browser with Playwright
gem "playwright-ruby-client", "~> 1.40", require: 'playwright'

group :development, :test do
# Auto-detect and warn about N+1 queries
gem "bullet"
Expand Down Expand Up @@ -258,4 +258,5 @@ end
group :test do
# Use system testing [https://guides.rubyonrails.org/testing.html#system-testing]
gem "capybara"
gem "capybara-playwright-driver"
end
19 changes: 10 additions & 9 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ GEM
minitest (>= 5.1)
mutex_m
tzinfo (~> 2.0)
addressable (2.8.5)
addressable (2.8.6)
public_suffix (>= 2.0.2, < 6.0)
after_party (1.11.2)
annotate (3.2.0)
Expand Down Expand Up @@ -150,6 +150,9 @@ GEM
rack-test (>= 0.6.3)
regexp_parser (>= 1.5, < 3.0)
xpath (~> 3.2)
capybara-playwright-driver (0.5.0)
capybara
playwright-ruby-client (>= 1.16.0)
coderay (1.1.3)
concurrent-ruby (1.2.2)
connection_pool (2.4.1)
Expand Down Expand Up @@ -357,6 +360,9 @@ GEM
activerecord (>= 5.2)
activesupport (>= 5.2)
phonelib (0.6.58)
playwright-ruby-client (1.40.0)
concurrent-ruby (>= 1.1.6)
mime-types (>= 3.0)
premailer (1.21.0)
addressable
css_parser (>= 1.12.0)
Expand Down Expand Up @@ -447,7 +453,7 @@ GEM
sorbet-runtime (>= 0.5.9204)
rdoc (6.6.1)
psych (>= 4.0.0)
regexp_parser (2.8.2)
regexp_parser (2.8.3)
reline (0.4.1)
io-console (~> 0.5)
rerun (0.14.0)
Expand Down Expand Up @@ -510,11 +516,6 @@ GEM
ffi (~> 1.12)
ruby2_keywords (0.0.5)
ruby_http_client (3.5.5)
rubyzip (2.3.2)
selenium-webdriver (4.15.0)
rexml (~> 3.2, >= 3.2.5)
rubyzip (>= 1.2.2, < 3.0)
websocket (~> 1.0)
sendgrid-ruby (6.7.0)
ruby_http_client (~> 3.4)
sentry-rails (5.14.0)
Expand Down Expand Up @@ -599,7 +600,6 @@ GEM
bindex (>= 0.4.0)
railties (>= 6.0.0)
webrick (1.8.1)
websocket (1.2.10)
websocket-driver (0.7.6)
websocket-extensions (>= 0.1.0)
websocket-extensions (0.1.5)
Expand Down Expand Up @@ -636,6 +636,7 @@ DEPENDENCIES
bullet
can_has_validations (~> 1.8)
capybara
capybara-playwright-driver
concurrent-ruby (~> 1.1)
date_validator (~> 0.12.0)
debug
Expand Down Expand Up @@ -673,6 +674,7 @@ DEPENDENCIES
pg (~> 1.5)
pg_search (~> 2.3)
phonelib (~> 0.6.55)
playwright-ruby-client (~> 1.40)
premailer-rails (~> 1.12)
pry
pry-doc
Expand Down Expand Up @@ -700,7 +702,6 @@ DEPENDENCIES
rubocop-sorbet
ruby-lsp
ruby-vips (~> 2.1)
selenium-webdriver (~> 4.11)
sendgrid-ruby (~> 6.6)
sentry-rails (~> 5.9)
silencer (~> 2.0)
Expand Down
2 changes: 1 addition & 1 deletion Procfile.test
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
docker: docker compose up --abort-on-container-exit postgres-test
postgres: sleep 0.5 && docker compose logs -f --no-log-prefix postgres-test
vite-ssr: bin/vite ssr
rails: bin/rails db:prepare && bin/rails test:all || exit -1
rails: sleep 1 && bin/rails db:prepare && bin/rails test:all || exit -1
2 changes: 1 addition & 1 deletion app/components/ResumeLayout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ const ResumeLayout: FC<ResumeLayoutProps> = ({ printable, children }) => (
mb={printable ? 0 : 135}
bg="var(--mantine-color-white)"
c="var(--mantine-color-black)"
className={classes.container}
className={cx("resume-layout", classes.container)}
{...(printable && { "data-printable": true })}
>
<Stack gap="xs">{children}</Stack>
Expand Down
74 changes: 22 additions & 52 deletions app/controllers/resumes_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -29,14 +29,11 @@ def show
render(json: Resume.current(variant: variant&.to_sym))
end
format.pdf do
data = print_resume(variant: variant&.to_sym)
name = ["kai-xie-resume", variant].compact.join("--")
send_data(
data,
filename: "#{name}.pdf",
type: "application/pdf",
disposition: "inline",
)
Tempfile.open([name, ".pdf"]) do |tempfile|
print_resume_to_tempfile(tempfile, variant: variant&.to_sym)
send_file(tempfile.path, disposition: "inline")
end
end
end
end
Expand All @@ -51,54 +48,27 @@ def self.print_resume_semaphore

# == Helpers
sig do
returns(T.all(
Selenium::WebDriver::Chrome::Driver,
Selenium::WebDriver::DriverExtensions::PrintsPage,
))
params(tempfile: Tempfile, variant: T.nilable(Symbol)).void
end
def webdriver
@webdriver ||= T.let(
Selenium::WebDriver.for(
:chrome,
options: Selenium::WebDriver::Chrome::Options.new.tap do |options|
options = T.let(options, Selenium::WebDriver::Chrome::Options)
options.add_argument("--headless")
options.add_argument("--window-size=1400,1000")
options.add_argument("--kiosk-printing")
if OS.linux?
options.add_argument("--no-sandbox")
options.add_argument("--disable-dev-shm-usage")
end
end,
),
T.nilable(T.all(
Selenium::WebDriver::Chrome::Driver,
Selenium::WebDriver::DriverExtensions::PrintsPage,
)),
)
end

sig { params(variant: T.nilable(Symbol)).returns(String) }
def print_resume(variant:)
def print_resume_to_tempfile(tempfile, variant: nil)
self.class.print_resume_semaphore.acquire do
params = { variant:, _printable: true }
url = resume_url(
protocol: "http",
host: "localhost",
port: ENV.fetch("RAILS_PORT") { 3000 }.to_i,
**params.compact,
)
driver = webdriver
driver.get(url)
Selenium::WebDriver::Wait.new.until do
driver.execute_script(
"return window.performance.timing.loadEventEnd > 0",
) && driver.execute_script(
'return window.performance.getEntriesByType("paint").length > 0',
)
Playwright.create(
playwright_cli_executable_path: "playwright",
) do |playwright|
playwright.chromium.launch do |browser|
page = T.let(browser.new_page, Playwright::Page)
params = { variant:, _printable: true }
url = resume_url(
protocol: "http",
host: "localhost",
port: request.port,
**params.compact,
)
page.goto(url)
page.wait_for_selector(".resume-layout")
page.pdf(path: tempfile.path)
end
end
page_str = driver.print_page
Base64.decode64(page_str)
end
end
end
6 changes: 5 additions & 1 deletion bin/setup
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,13 @@ FileUtils.chdir APP_ROOT do
puts "\n=> Install Python dependencies"
system! "poetry install --no-root"

puts "\n=> Installing githooks"
puts "\n=> Installing git hooks"
system! "bin/yarn husky install"

puts "\n=> Installing Playwright"
system! "bin/yarn global add playwright"
system! "playwright install"

# puts "\n=> Copying sample files"
# unless File.exist?("config/database.yml")
# FileUtils.cp "config/database.yml.sample", "config/database.yml"
Expand Down
6 changes: 3 additions & 3 deletions bin/test
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,6 @@ bin/rails assets:clobber
bin/rails assets:precompile

echo -e "\n=> Running tests"
set +e
bin/overmind start -f Procfile.test --no-port "$@"
if [ "$?" -ne 130 ]; then exit $?; fi
EXIT_CODE=0
bin/overmind start -f Procfile.test --no-port "$@" || EXIT_CODE=$?
if [ "$EXIT_CODE" -ne 130 ]; then exit $EXIT_CODE; fi
15 changes: 5 additions & 10 deletions config/initializers/capybara.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,9 @@

return unless defined?(Capybara)

if Rails.env.test?
Capybara.register_driver(:headless_chrome) do |app|
Capybara::Selenium::Driver.new(
app,
browser: :chrome,
options: Selenium::WebDriver::Chrome::Options.new(
args: %w[headless window-size=1400,1000],
),
)
end
Capybara.default_max_wait_time = 15
Capybara.register_driver(:playwright) do |app|
Capybara::Playwright::Driver.new(app)
end
Capybara.default_driver = :playwright
Capybara.javascript_driver = :playwright
Loading

0 comments on commit 4255fd8

Please sign in to comment.