Skip to content

Commit 9037689

Browse files
committed
chore(tests): add TestClient for e2e tests
1 parent d6fe14c commit 9037689

File tree

2 files changed

+101
-0
lines changed

2 files changed

+101
-0
lines changed

test_integrations/phoenix_app/config/runtime.exs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,21 @@ if System.get_env("PHX_SERVER") do
2020
config :phoenix_app, PhoenixAppWeb.Endpoint, server: true
2121
end
2222

23+
# For e2e tracing tests, use the TestClient to log events to a file
24+
# This must be in runtime.exs because the env var is set at runtime, not compile time
25+
if System.get_env("SENTRY_E2E_TEST_MODE") == "true" do
26+
config :sentry,
27+
dsn: "https://public@sentry.example.com/1",
28+
client: PhoenixApp.TestClient
29+
else
30+
# Allow runtime configuration of Sentry DSN and environment
31+
if dsn = System.get_env("SENTRY_DSN") do
32+
config :sentry,
33+
dsn: dsn,
34+
environment_name: System.get_env("SENTRY_ENVIRONMENT") || config_env()
35+
end
36+
end
37+
2338
if config_env() == :prod do
2439
# database_url =
2540
# System.get_env("DATABASE_URL") ||
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
defmodule PhoenixApp.TestClient do
2+
@moduledoc """
3+
A test Sentry client that logs envelopes to a file for e2e test validation.
4+
5+
This client mimics the behavior of Sentry::DebugTransport in sentry-ruby,
6+
logging all envelopes to a file that can be read by Playwright tests.
7+
"""
8+
9+
require Logger
10+
11+
@behaviour Sentry.HTTPClient
12+
13+
@impl true
14+
def post(_url, _headers, body) do
15+
log_envelope(body)
16+
17+
# Return success response
18+
{:ok, 200, [], ~s({"id":"test-event-id"})}
19+
end
20+
21+
defp log_envelope(body) when is_binary(body) do
22+
log_file = Path.join([File.cwd!(), "tmp", "sentry_debug_events.log"])
23+
24+
# Ensure the tmp directory exists
25+
log_dir = Path.dirname(log_file)
26+
File.mkdir_p!(log_dir)
27+
28+
# Parse the envelope binary to extract events and headers
29+
case parse_envelope(body) do
30+
{:ok, envelope_data} ->
31+
# Write the envelope data as JSON
32+
json = Jason.encode!(envelope_data)
33+
File.write!(log_file, json <> "\n", [:append])
34+
35+
{:error, reason} ->
36+
Logger.warning("Failed to parse envelope for logging: #{inspect(reason)}")
37+
end
38+
rescue
39+
error ->
40+
Logger.warning("Failed to log envelope: #{inspect(error)}")
41+
end
42+
43+
defp parse_envelope(body) when is_binary(body) do
44+
# Envelope format: header\nitem_header\nitem_payload[\nitem_header\nitem_payload...]
45+
# See: https://develop.sentry.dev/sdk/envelopes/
46+
47+
lines = String.split(body, "\n")
48+
49+
with {:ok, header_line, rest} <- get_first_line(lines),
50+
{:ok, envelope_headers} <- Jason.decode(header_line),
51+
{:ok, items} <- parse_items(rest) do
52+
53+
envelope = %{
54+
headers: envelope_headers,
55+
items: items
56+
}
57+
58+
{:ok, envelope}
59+
else
60+
error -> {:error, error}
61+
end
62+
end
63+
64+
defp get_first_line([first | rest]), do: {:ok, first, rest}
65+
defp get_first_line([]), do: {:error, :empty_envelope}
66+
67+
defp parse_items(lines), do: parse_items(lines, [])
68+
69+
defp parse_items([], acc), do: {:ok, Enum.reverse(acc)}
70+
71+
defp parse_items([item_header_line, payload_line | rest], acc) do
72+
with {:ok, _item_header} <- Jason.decode(item_header_line),
73+
{:ok, payload} <- Jason.decode(payload_line) do
74+
parse_items(rest, [payload | acc])
75+
else
76+
_error ->
77+
# Skip malformed items
78+
parse_items(rest, acc)
79+
end
80+
end
81+
82+
defp parse_items([_single_line], acc) do
83+
# Handle trailing empty line
84+
{:ok, Enum.reverse(acc)}
85+
end
86+
end

0 commit comments

Comments
 (0)