Files
ubicloud/bin/regen-screenshots
2025-05-26 08:14:08 +03:00

344 lines
10 KiB
Ruby
Executable File

#!/usr/bin/env ruby
# frozen_string_literal: true
DOCUMENTATION_DIR = "../documentation/"
unless File.directory?(DOCUMENTATION_DIR)
warn "Documentation site must be checked out in ../documentation"
exit(1)
end
require "find"
require "capybara"
require "capybara/dsl"
require "capybara/cuprite"
require "puma/cli"
require "nio"
require "securerandom"
ENV["RACK_ENV"] = "test"
# Enable shared connections for Sequel DB, to allow server and screenshot code to share the same transaction
ENV["SHARED_CONNECTION"] = "1"
# Set fake stripe secret key in order to take screenshots of billing pages
ENV["STRIPE_SECRET_KEY"] = "1"
# Set fake GitHub app name in order to take screenshots of GitHub Runner pages
ENV["GITHUB_APP_NAME"] = "1"
require_relative "../loader"
PORT = 8383
db_name = DB.get { current_database.function }
raise "Doesn't look like a test database (#{db_name}), not generating screenshots" unless db_name.end_with?("test")
Capybara.exact = true
Capybara.default_selector = :css
Capybara.default_driver = :cuprite
Capybara.server_port = PORT
Capybara.register_driver(:cuprite) do |app|
Capybara::Cuprite::Driver.new(app, window_size: [1200, 800], browser_options: {timeout: 15}, base_url: "http://localhost:#{PORT}")
end
require "tilt/erubi"
require "tilt/string"
queue = Queue.new
server = Puma::CLI.new(["-s", "-e", "test", "-b", "tcp://localhost:#{PORT}", "-t", "1:1", "config.ru"])
server.launcher.events.on_booted { queue.push(nil) }
Thread.new do
server.launcher.run
end
queue.pop
::Mail.defaults do
delivery_method :test
end
class RegenScreenshots
include Capybara::DSL
SCREENSHOTS = {}
Find.find(DOCUMENTATION_DIR) do |file|
if File.file?(file) && file.end_with?("screenshot.png")
SCREENSHOTS[file.delete_prefix(DOCUMENTATION_DIR)] = file
end
end
def screenshot(filename)
unless (path = SCREENSHOTS.delete(filename))
raise "No existing screenshot for #{filename} in documentation site"
end
# rubocop:disable Lint/Debugger
save_screenshot(path:)
# rubocop:enable Lint/Debugger
puts "Saved screenshot: #{filename}"
end
def resize(height, width: 1200)
Capybara.current_session.driver.browser.resize(width:, height:)
end
def call
visit "/"
click_link "Create a new account"
password = SecureRandom.base64(48)
fill_in "Full Name", with: "Demo"
fill_in "Email Address", with: "demo@example.com"
fill_in "Password", with: password
fill_in "Password Confirmation", with: password
click_button "Create Account"
mail = Mail::TestMailer.deliveries.shift
body = mail.parts[1].decoded
unless (match = %r{(/verify-account\?key=[^"]+)"}.match(body))
raise "no verify link in email"
end
visit match[1]
click_button "Verify Account"
project = Project.first
resize(900, width: 1600)
visit "/"
screenshot "quick-start/managed-services-1-screenshot.png"
find("#billing-icon").hover
screenshot "github-actions-integration/quickstart-1-screenshot.png"
Project.define_method(:has_valid_payment_method?) { true }
click_link "GitHub Runners"
screenshot "github-actions-integration/quickstart-2-screenshot.png"
GithubInstallation.create(installation_id: 123, name: "ubicloud-demo", type: "Organization", project_id: project.id, allocator_preferences: {"family_filter" => ["premium", "standard"]})
page.refresh
click_link "Settings", class: "text-gray-500"
screenshot "github-actions-integration/use-premium-runners-1-screenshot.png"
resize(650)
click_link "Tokens"
screenshot "quick-start/cli-1-screenshot.png"
click_button "Create Token"
ApiKey.dataset.update(id: "bf444ee6-2532-8153-975e-af787dbc796e")
page.refresh
screenshot "quick-start/cli-2-screenshot.png"
click_link "PostgreSQL"
screenshot "managed-postgresql/overview-1-screenshot.png"
resize(1400)
click_link "Create PostgreSQL Database"
screenshot "quick-start/using-kamal-with-ubicloud-3-screenshot.png"
pg_resource = PostgresResource.create(
name: "postgresql-demo",
location_id: Location::HETZNER_FSN1_ID,
target_vm_size: "standard-2",
target_storage_size_gib: 10,
superuser_password: "1",
project_id: project.id
) do |pg|
pg.id = UBID.parse("pgmjy3v4ef1y7gdpzv6b3fchef").to_uuid
end
Project.define_method(:postgres_resources_dataset) do |*a|
super(*a).with_extend do
define_method(:all) { [pg_resource] }
define_method(:first) { |*| pg_resource }
end
end
PostgresResource.define_method(:display_state) { "running" }
PostgresResource.define_method(:connection_string) { "sample-connection-string" }
PostgresResource.define_method(:ca_certificates) { "certs" }
Authorization.define_singleton_method(:authorize) { |*| }
resize(800)
click_link "PostgreSQL"
click_link "postgresql-demo"
screenshot "managed-postgresql/overview-2-screenshot.png"
click_link "Kubernetes"
click_link "Create Kubernetes Cluster"
fill_in "Cluster Name", with: "kubernetes-demo"
find('input[name="cp_nodes"][value="3"]:not([disabled])').trigger("click")
find('select#worker_nodes option[value="5"]:not([disabled])').select_option
resize(900)
screenshot "managed-kubernetes/create-screenshot.png"
kc_ubid = "kcj4veqfy46a4pcxpmj3dzwzf5"
kn_ubid = "kna6c1cyxqba5pbmfthkb0xawa"
k8s_cluster = KubernetesCluster.create(
name: "kubernetes-demo",
version: "v1.32",
cp_node_count: 3,
location_id: Location::HETZNER_FSN1_ID,
target_node_size: "standard-2",
private_subnet_id: Prog::Vnet::SubnetNexus.assemble(
project.id,
name: "#{kc_ubid}-subnet",
location_id: Location::HETZNER_FSN1_ID,
ipv4_range: Prog::Vnet::SubnetNexus.random_private_ipv4(Location[Location::HETZNER_FSN1_ID], project, 18).to_s
).subject.id,
project_id: project.id
) do |kc|
kc.id = UBID.parse(kc_ubid).to_uuid
end
k8s_nodepool = KubernetesNodepool.create(
name: "kubernetes-demo-np",
node_count: 5,
kubernetes_cluster_id: k8s_cluster.id,
target_node_size: "standard-2"
) do |kn|
kn.id = UBID.parse(kn_ubid).to_uuid
end
Prog::Vnet::LoadBalancerNexus.assemble(
k8s_cluster.private_subnet_id,
name: k8s_cluster.services_load_balancer_name,
algorithm: "hash_based",
src_port: 443,
dst_port: 6443,
health_check_endpoint: "/",
health_check_protocol: "tcp",
stack: LoadBalancer::Stack::IPV4
)
["le9ec", "e12en", "zd3ka"].each do |suffix|
k8s_cluster.add_cp_vm Prog::Vm::Nexus.assemble_with_sshable(
project.id,
sshable_unix_user: "ubi",
name: "#{kc_ubid}-#{suffix}",
location_id: k8s_cluster.location.id,
private_subnet_id: k8s_cluster.private_subnet_id,
enable_ip4: true
).subject
end
["ubicl", "krn71", "fysgd", "mant4", "m0h11"].each do |suffix|
k8s_nodepool.add_vm Prog::Vm::Nexus.assemble_with_sshable(
project.id,
sshable_unix_user: "ubi",
name: "#{kn_ubid}-#{suffix}",
location_id: k8s_cluster.location.id,
private_subnet_id: k8s_cluster.private_subnet_id,
enable_ip4: true
).subject
end
Project.define_method(:kubernetes_clusters_dataset) do |*a|
super(*a).with_extend do
define_method(:all) { [k8s_cluster] }
define_method(:first) { |*| k8s_cluster }
end
end
KubernetesCluster.define_method(:display_state) { "running" }
Vm.define_method(:display_state) { "running" }
LoadBalancer.define_method(:hostname) { "f9f2x4td37-services.k8s.ubicloud.com" }
click_link "Kubernetes"
click_link "kubernetes-demo"
resize(1400)
screenshot "managed-kubernetes/overview-screenshot.png"
resize(800)
click_link "Users"
fill_in "email", with: "other@example.com"
find("input[name=email]").click
screenshot "security/users-1-screenshot.png"
account2 = Account.create(email: "other@example.com", name: "Other")
click_button "Invite"
page.refresh
page.evaluate_script("$('#user_policy_#{account2.ubid}').focus()")
screenshot "security/users-2-screenshot.png"
click_link "Access Control"
access_control_path = page.current_path
screenshot "security/access-control-1-screenshot.png"
click_link "subject-tags-link"
screenshot "security/subject-tag-1-screenshot.png"
fill_in "name", with: "System-Admins"
click_button "Create"
fill_in "name", with: "Network-Admins"
click_button "Create"
page.refresh
fill_in "name", with: "Database-Admins"
page.evaluate_script("$('#name').focus()")
screenshot "security/subject-tag-2-screenshot.png"
click_button "Create"
resize(1020)
click_link "#{SubjectTag[name: "System-Admins"].ubid}-edit"
screenshot "security/subject-tag-3-screenshot.png"
resize(1140)
check "add[]-#{account2.ubid}-0"
click_button "Add Members"
page.refresh
screenshot "security/subject-tag-4-screenshot.png"
resize(800)
visit access_control_path
click_link "action-tags-link"
fill_in "name", with: "Networking"
click_button "Create"
page.refresh
screenshot "security/action-tag-1-screenshot.png"
resize(1140)
click_link "Manage"
check "add[]-tazzzzzzzz021gzzzz0fw0a110-0"
check "add[]-tazzzzzzzz021gzzzz01b0a111-0"
check "add[]-tazzzzzzzz021gzzzz0ps0a111-0"
screenshot "security/action-tag-2-screenshot.png"
resize(800)
click_button "Add Members"
page.refresh
screenshot "security/action-tag-3-screenshot.png"
resize(850)
visit access_control_path
3.times do
click_button "New Access Control Entry"
end
screenshot "security/access-control-2-screenshot.png"
select "System-Admins", from: "ace-select-1-0"
select "Vm:all", from: "ace-select-1-1"
select "Network-Admins", from: "ace-select-2-0"
select "Networking", from: "ace-select-2-1"
select "Database-Admins", from: "ace-select-3-0"
select "Postgres:all", from: "ace-select-3-1"
screenshot "security/access-control-3-screenshot.png"
resize(1800)
click_link "Compute"
click_link "Create Virtual Machine"
screenshot "quick-start/managed-services-2-screenshot.png"
end
end
DB.transaction(rollback: :always, auto_savepoint: true) do |conn|
DB.temporarily_release_connection(conn) do
RegenScreenshots.new.call
end
end
unless RegenScreenshots::SCREENSHOTS.empty?
warn "Missing screenshots:", RegenScreenshots::SCREENSHOTS.keys.sort
exit(1)
end