Skip to content
Draft
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
5 changes: 4 additions & 1 deletion lib/devhub/coverbot/test_reports/actions/get_flaky_tests.ex
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ defmodule Devhub.Coverbot.TestReports.Actions.GetFlakyTests do
class_name: String.t(),
failure_count: non_neg_integer(),
first_failure_at: DateTime.t(),
last_failure_at: DateTime.t(),
commit_sha: String.t(),
info: map()
}
Expand All @@ -41,6 +42,7 @@ defmodule Devhub.Coverbot.TestReports.Actions.GetFlakyTests do
class_name: tr3.class_name,
test_name: tr3.test_name,
first_failure_at: min(tr3.inserted_at),
last_failure_at: max(tr3.inserted_at),
commit_sha: fragment("(array_agg(? ORDER BY ? ASC))[1]", c.sha, tr3.inserted_at)
}

Expand All @@ -53,12 +55,13 @@ defmodule Devhub.Coverbot.TestReports.Actions.GetFlakyTests do
where: tsr.test_suite_id == ^test_suite_id,
where: tr.status == ^:failed,
where: tsr.id in subquery(recent_runs_query),
group_by: [tr.test_name, tr.class_name, ff.first_failure_at, ff.commit_sha],
group_by: [tr.test_name, tr.class_name, ff.first_failure_at, ff.last_failure_at, ff.commit_sha],
select: %{
test_name: tr.test_name,
class_name: tr.class_name,
failure_count: count(tr.id),
first_failure_at: ff.first_failure_at,
last_failure_at: ff.last_failure_at,
commit_sha: ff.commit_sha,
# use aggregate function to get most recent info since tr.info is not in GROUP BY
info: fragment("(array_agg(? ORDER BY ? DESC))[1]", tr.info, tr.inserted_at)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,7 @@ defmodule Devhub.Coverbot.TestReports.Actions.GetFlakyTestsTest do
class_name: "TestModule",
failure_count: 3,
first_failure_at: always_failing_first_failure_datetime,
last_failure_at: always_failing_last_failure_datetime,
test_name: "always_failing",
# first (ever) failure was in commit1, but count is only from last 3 runs
commit_sha: "commit1",
Expand All @@ -183,6 +184,7 @@ defmodule Devhub.Coverbot.TestReports.Actions.GetFlakyTestsTest do
class_name: "TestModule",
failure_count: 2,
first_failure_at: flaky_first_failure_datetime,
last_failure_at: flaky_last_failure_datetime,
test_name: "flaky",
# first (ever) failure was in commit2
commit_sha: "commit2",
Expand All @@ -193,6 +195,9 @@ defmodule Devhub.Coverbot.TestReports.Actions.GetFlakyTestsTest do
Coverbot.get_flaky_tests(test_suite.id, 3)

assert Timex.equal?(flaky_first_failure_datetime, ~U[2024-01-02 10:00:00Z])
assert Timex.equal?(flaky_last_failure_datetime, ~U[2024-01-03 10:00:00Z])

assert Timex.equal?(always_failing_first_failure_datetime, ~U[2024-01-01 10:00:00Z])
assert Timex.equal?(always_failing_last_failure_datetime, ~U[2024-01-04 10:00:00Z])
end
end
38 changes: 28 additions & 10 deletions lib/devhub_web/live/coverbot/test_reports/test_suite.ex
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,13 @@ defmodule DevhubWeb.Live.Coverbot.TestReports.TestSuite do

def mount(%{"test_suite_id" => test_suite_id}, _session, socket) do
{:ok, test_suite} = Coverbot.get_test_suite(test_suite_id)
number_of_past_runs = 10

socket
|> assign(
test_suite: test_suite,
page_title: "Test Suite",
number_of_past_runs: number_of_past_runs,
breadcrumbs: [
%{title: "Test Suites", path: "/coverbot/test-reports"},
%{
Expand All @@ -26,7 +28,7 @@ defmodule DevhubWeb.Live.Coverbot.TestReports.TestSuite do
skipped_tests: AsyncResult.loading()
)
|> assign_async([:flaky_tests], fn ->
{:ok, %{flaky_tests: Coverbot.get_flaky_tests(test_suite_id, 10)}}
{:ok, %{flaky_tests: Coverbot.get_flaky_tests(test_suite_id, number_of_past_runs)}}
end)
|> assign_async([:skipped_tests], fn ->
{:ok, %{skipped_tests: Coverbot.get_skipped_tests(test_suite_id)}}
Expand All @@ -41,13 +43,19 @@ defmodule DevhubWeb.Live.Coverbot.TestReports.TestSuite do
<.page_header title="Flaky tests" />
<.async_result :let={flaky_tests} assign={@flaky_tests}>
<:loading>
<div class="relative z-30 m-2 text-gray-900">Loading flaky tests</div>
<div id="flaky-tests-spinner" class="flex items-center justify-center">
<div class="size-10">
<.spinner />
</div>
</div>
</:loading>
<:failed :let={_failure}>
<div class="relative z-30 m-2 text-gray-900">There was an error loading flaky tests</div>
</:failed>
<%= if Enum.empty?(flaky_tests) do %>
<div class="relative z-30 m-2 text-gray-900">No flaky tests in the past 10 days</div>
<div class="relative z-30 m-2 text-gray-900">
No flaky tests in the past {@number_of_past_runs} test runs
</div>
<% else %>
<.table
id="flaky-tests-data"
Expand All @@ -63,7 +71,12 @@ defmodule DevhubWeb.Live.Coverbot.TestReports.TestSuite do
{test_run.failure_count}
</div>
</:col>
<:col :let={test_run} label="First time failed" class="w-1/5">
<:col :let={test_run} label="Last time failed" class="w-1/5">
<div class="flex items-center justify-between text-xs">
<format-date date={test_run.last_failure_at} format="relative-datetime" />
</div>
</:col>
<:col :let={test_run} label="First time failed" class="w-1/4">
<div class="flex items-center justify-between text-xs">
<format-date date={test_run.first_failure_at} format="relative-datetime" />
<div class="flex items-center gap-2">
Expand All @@ -88,15 +101,21 @@ defmodule DevhubWeb.Live.Coverbot.TestReports.TestSuite do
<.page_header title="Skipped tests" />
<.async_result :let={skipped_tests} assign={@skipped_tests}>
<:loading>
<div class="relative z-30 m-2 text-gray-900">Loading skipped tests</div>
<div id="skipped-tests-spinner" class="flex items-center justify-center">
<div class="size-10">
<.spinner />
</div>
</div>
</:loading>
<:failed :let={_failure}>
<div class="relative z-30 m-2 text-gray-900">
There was an error loading skipped tests
</div>
</:failed>
<%= if Enum.empty?(skipped_tests) do %>
<div class="relative z-30 m-2 text-gray-900">No skipped tests in the past 10 days</div>
<div class="relative z-30 m-2 text-gray-900">
No skipped tests in the most recent test run
</div>
<% else %>
<.table
id="skipped-tests-data"
Expand All @@ -107,10 +126,9 @@ defmodule DevhubWeb.Live.Coverbot.TestReports.TestSuite do
<p class="text-xs">{test_run.test_name}</p>
<p class="text-xs text-gray-500">{test_run.class_name}</p>
</:col>
<:col label="" class="w-1/12">
<div class="text-xs"></div>
</:col>
<:col :let={test_run} label="First time skipped" class="w-1/5">
<:col label="" class="w-1/12"></:col>
<:col label="" class="w-1/5"></:col>
<:col :let={test_run} label="First time skipped" class="w-1/4">
<div class="flex items-center justify-between text-xs">
<format-date date={test_run.test_suite_run.inserted_at} format="relative-datetime" />
<div class="flex items-center gap-2">
Expand Down
16 changes: 12 additions & 4 deletions lib/devhub_web/live/coverbot/test_reports/test_suite_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ defmodule DevhubWeb.Live.Coverbot.TestReports.TestSuiteTest do
class_name: "TestModule",
failure_count: 3,
first_failure_at: ~U[2024-01-01 10:00:00Z],
last_failure_at: ~U[2024-01-10 10:00:00Z],
commit_sha: "abc123",
info: %{
"message" => "Test failed randomly",
Expand Down Expand Up @@ -148,8 +149,8 @@ defmodule DevhubWeb.Live.Coverbot.TestReports.TestSuiteTest do
# Wait for async assigns to resolve
current_html = render_async(view, 1000)

assert current_html =~ "No flaky tests in the past 10 days"
assert current_html =~ "No skipped tests in the past 10 days"
assert current_html =~ "No flaky tests in the past 10 test runs"
assert current_html =~ "No skipped tests in the most recent test run"

refute has_element?(view, "#flaky-tests-data")
refute has_element?(view, "#skipped-tests-data")
Expand Down Expand Up @@ -183,8 +184,15 @@ defmodule DevhubWeb.Live.Coverbot.TestReports.TestSuiteTest do

{:ok, _view, html} = live(conn, ~p"/coverbot/test-reports/#{test_suite_id}")

assert html =~ "Loading flaky tests"
assert html =~ "Loading skipped tests"
refute html
|> Floki.parse_document!()
|> Floki.get_by_id("flaky-tests-spinner")
|> is_nil()

refute html
|> Floki.parse_document!()
|> Floki.get_by_id("skipped-tests-spinner")
|> is_nil()
end

test "shows failed state when flaky loading fails", %{conn: conn, organization: organization} do
Expand Down
Loading