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

Add tests for wallaby's behavior when starting chromedriver #510

Closed
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
38 changes: 38 additions & 0 deletions test/support/application_control.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
defmodule Wallaby.TestSupport.ApplicationControl do
@moduledoc """
Test helpers for starting/stopping wallaby during test setup
"""

import ExUnit.Assertions, only: [flunk: 1]
import ExUnit.Callbacks, only: [on_exit: 1]
import Wallaby.SettingsTestHelpers

@doc """
Stops the wallaby application and ensures its restarted
before the next test
"""
def stop_wallaby(_) do
Application.stop(:wallaby)

on_exit(fn ->
case Application.start(:wallaby) do
result when result in [:ok, {:error, {:already_started, :wallaby}}] ->
:ok

result ->
flunk("failed to restart wallaby: #{inspect(result)}")
end
end)
end

@doc """
Set's the current driver to chromedriver

Note: This is not safe for use with `async: true`
"""
def set_to_chromedriver(_) do
ensure_setting_is_reset(:wallaby, :driver)

:ok = Application.put_env(:wallaby, :driver, Wallaby.Experimental.Chrome)
end
end
69 changes: 69 additions & 0 deletions test/support/chrome/fake_chromedriver_script.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
defmodule Wallaby.TestSupport.Chrome.FakeChromedriverScript do
@moduledoc """
A fake chromedriver script that enables checking the argv options
passed when process is started.

This is very useful for integration style testing.
"""

@type script_path :: String.t()
@type test_script_opt :: {:version, String}

@spec write_test_script!(String.t(), [test_script_opt]) :: script_path
def write_test_script!(directory, opts \\ []) when is_list(opts) do
script_name = "test_script-#{random_string()}"
script_path = Path.join(directory, script_name)
output_path = Path.join(directory, output_filename(script_name))
contents = script_contents(output_path, opts)

:ok = File.write(script_path, contents)
:ok = File.chmod(script_path, 0o755)

script_path
end

@spec fetch_last_argv(script_path) :: {:ok, String.t()} | {:error, :not_found}
def fetch_last_argv(script_path) do
directory = Path.dirname(script_path)
script_name = Path.basename(script_path)
output_path = Path.join(directory, output_filename(script_name))

case File.read(output_path) do
{:ok, contents} ->
last_line =
contents
|> String.split("\n", trim: true)
|> List.last()

{:ok, last_line}

{:error, :enoent} ->
{:error, :not_found}
end
end

defp script_contents(output_path, opts) do
version = Keyword.get(opts, :version, "79.0.3945.36")

"""
#!/bin/sh

if [ "$1" = "--version" ]; then
echo "ChromeDriver #{version}"
else
echo $@ >> #{output_path}
fi
"""
end

defp output_filename(script_name) do
"#{script_name}-output"
end

defp random_string do
0x100000000
|> :rand.uniform()
|> Integer.to_string(36)
|> String.downcase()
end
end
31 changes: 31 additions & 0 deletions test/support/test_workspace.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
defmodule Wallaby.TestSupport.TestWorkspace do
@moduledoc """
Test helpers that create temporary directory that exists
for the lifetime of the test.
"""

import ExUnit.Callbacks, only: [on_exit: 1]

alias Wallaby.Driver.TemporaryPath

def create_test_workspace(_) do
workspace_path = gen_tmp_path()
:ok = File.mkdir_p!(workspace_path)

on_exit(fn ->
File.rm_rf!(workspace_path)
end)

[workspace_path: workspace_path]
end

defp gen_tmp_path do
base_dir =
Path.join(
System.tmp_dir!(),
Application.get_env(:wallaby, :tmp_dir_prefix, "")
)

TemporaryPath.generate(base_dir)
end
end
58 changes: 58 additions & 0 deletions test/wallaby/experimental/chrome_test.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
defmodule Wallaby.Experimental.ChromeTest do
use ExUnit.Case, async: false

import Wallaby.SettingsTestHelpers
import Wallaby.TestSupport.ApplicationControl
import Wallaby.TestSupport.TestWorkspace

alias Wallaby.TestSupport.Chrome.FakeChromedriverScript

setup [
:stop_wallaby,
:set_to_chromedriver,
:create_test_workspace
]

@moduletag :capture_log

test "starting wallaby with chromedriver calls the executable with the correct options", %{
workspace_path: workspace_path
} do
ensure_setting_is_reset(:wallaby, :chromedriver)

script_path = FakeChromedriverScript.write_test_script!(workspace_path)
Application.put_env(:wallaby, :chromedriver, path: script_path)

assert :ok = Application.start(:wallaby)

# Application startup seems to call the FakeChromedriverScript async
Process.sleep(500)

{switches, []} =
case FakeChromedriverScript.fetch_last_argv(script_path) do
{:ok, argv} ->
argv
|> String.split()
|> OptionParser.parse!(switches: [], allow_nonexistent_atoms: true)

{:error, :not_found} ->
flunk("Fake chromedriver script not called. (Script: #{script_path})")
end

assert {port, remaining_switches} = Keyword.pop(switches, :port)
assert is_binary(port)

assert remaining_switches == [log_level: "OFF"]
end

test "wallaby fails to start if chromedriver's version is < 2.30", %{
workspace_path: workspace_path
} do
ensure_setting_is_reset(:wallaby, :chromedriver)

script_path = FakeChromedriverScript.write_test_script!(workspace_path, version: "2.29")
Application.put_env(:wallaby, :chromedriver, path: script_path)

assert {:error, _} = Application.start(:wallaby)
end
end