I cannot remember. I have kind of given up on Wallaby. I get random failures when I do any tests that involve more than 10 interactions (which I really really need - I want to test entire workflows that can include up to 100 interactions in a single test). Here is my setup anyway (I stopped getting that error so maybe it will help you). The sanity tests pass reliably for me (since they do a small number of interactions):
sanity_test.exs
defmodule MyApp.WallabyTest do
use MyAppWeb.WallabyCase, async: false
feature "login allows good user", %{session: session} do
session
|> auth_user(session, "use@myapp.comr", "wallaby-user-password")
end
feature "login denies non-existent user", %{session: session} do
session
|> visit("#{@backend_url}session/new")
|> find(@login_form, fn form ->
form
|> fill_in(@login_email_field, with: "a")
|> fill_in(@login_password_field, with: "a")
|> click(@login_submit_button)
end)
|> assert_has(css(".bg-red-100", text: "Wrong email or password"))
end
feature "frontend can be reached", %{session: session} do
session
|> visit("#{@frontend_url}")
|> assert_has(css("#home-wrapper"))
end
end
wallaby_case.ex
defmodule MyAppWeb.WallabyCase do
@moduledoc """
"""
use ExUnit.CaseTemplate
using do
quote do
use Wallaby.Feature
import Wallaby.{Browser, Query}
alias MyAppWeb.Router.Helpers, as: Routes
# absolute urls for backend and frontend
@backend_url "http://localhost:4002/"
@frontend_url "http://frontend:3000/"
# wallaby elements for logging in
@login_form css("form")
@login_email_field text_field("Email")
@login_password_field text_field("Password")
@login_submit_button button("Sign In")
defp auth_user(session, user, password) do
session
|> visit("#{@backend_url}session/new")
|> find(@login_form, fn form ->
form
|> fill_in(@login_email_field, with: user)
|> fill_in(@login_password_field, with: password)
|> click(@login_submit_button)
end)
|> assert_has(css("#orders-table"))
end
end
end
setup tags do
alias Ecto.Adapters.SQL.Sandbox
alias MyApp.Accounts.User
alias MyApp.{Repo, Seeds}
unless tags[:async] do
:ok = Sandbox.checkout(MyApp.Repo)
Sandbox.mode(MyApp.Repo, {:shared, self()})
end
Seeds.run()
%User{}
|> User.changeset(%{
email: "user@myapp.com",
name: "user",
password: "wallaby-user-password"
})
|> Repo.insert!()
:ok
end
end
docker-compose.override.yml
version: "3.8"
services:
db:
image: postgres:12.3
env_file:
- ./my-app-backend/docker/dev.env
restart: always
ports:
- "5432:5432"
volumes:
- db-data:/var/lib/postgresql/data
backend:
image: my-app-backend:local
build:
context: ./my-app-backend
dockerfile: ./docker/Dockerfile.dev
depends_on:
- db
- frontend # so the wallaby tests pass
env_file:
- ./my-app-backend/docker/dev.env
ports:
- "4000:4000"
volumes:
- /opt/my-app/assets/node_modules
- ./my-app-backend/assets:/opt/my-app/assets:ro
- ./my-app-backend/config:/opt/my-app/config:ro
- ./my-app-backend/lib:/opt/my-app/lib:ro
- ./my-app-backend/priv:/opt/my-app/priv
- ./my-app-backend/test:/opt/my-app/test:ro
- ./my-app-backend/seeds:/opt/my-app/seeds:ro
- ./my-app-backend/mix.exs:/opt/my-app/mix.exs:ro
- ./my-app-backend/mix.lock:/opt/my-app/mix.lock:ro
- ./my-app-backend/docker/.iex.exs:/opt/my-app/.iex.exs:ro
- ./my-app-backend/entrypoint.sh:/opt/my-app/entrypoint.sh:ro
- ./my-app-backend/dev/support:/opt/my-app/dev/support:ro
- ./.wallaby_screenshots:/opt/my-app/screenshots
stdin_open: true
tty: true
frontend:
image: my-app-frontend:local
build:
context: ./my-app-frontend
dockerfile: ./docker/Dockerfile.dev
env_file:
- ./my-app-frontend/docker/dev.env
ports:
- "3000:3000"
volumes:
- ./my-app-frontend:/opt/my-app:ro
- /opt/my-app/node_modules
stdin_open: true
tty: true
volumes:
db-data:
my-app-backend/docker/Dockerfile.dev
# https://github.com/c0b/docker-elixir/wiki/use-observer
FROM elixir:latest
RUN curl -sL https://deb.nodesource.com/setup_14.x | bash -
RUN apt update
RUN apt install -y git nodejs inotify-tools
RUN apt install -y chromium-driver
RUN mkdir -p /opt/my-app
WORKDIR /opt/my-app
RUN mix local.hex --force && \
mix local.rebar --force && \
mix archive.install --force hex phx_new
COPY mix.exs .
COPY mix.lock .
# copy the deps in dev environment for faster builds
COPY deps ./deps
RUN ["mix", "deps.get"]
RUN ["mix", "deps.compile"]
COPY assets ./assets
WORKDIR /opt/my-app/assets
RUN ["npm", "install"]
WORKDIR /opt/my-app
COPY config ./config
COPY lib ./lib
COPY seeds ./seeds
COPY priv ./priv
COPY test ./test
COPY dev/support ./dev/support
RUN ["mix", "compile"]
# compile deps in test environment for faster test runs when built
RUN export MIX_ENV=test && mix deps.compile
COPY ./entrypoint.sh ./entrypoint.sh
COPY docker/.iex.exs .iex.exs
COPY .iex.exs .
CMD ["/bin/bash", "entrypoint.sh"]
Note this is a setup for :dev
environment only. I hope it helps you and I hope someone else can spot some problem with it.