In one full run (241 of 242 passing) the home feed came back from a thread with fewer posts than it was left with, and passed three times alone. The feed takes a post out at once when the stream says it was deleted, and earlier tests do delete posts in that persona's home, but PrivaPub's log shows no federated Delete at that minute, so the cause is not proven. The test now allows for the deletions the stream reported during the trip and says the three numbers when it fails; with none reported, a shorter feed still fails, and coming back still may not read the home feed again. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LsXgEaXee4GCU1hwYgPJXw
58 lines
2.5 KiB
C#
58 lines
2.5 KiB
C#
using decePubClient.E2E.Support;
|
|
|
|
using Microsoft.Playwright;
|
|
|
|
namespace decePubClient.E2E.Actions
|
|
{
|
|
// Coming back to the feed from a thread shows it as it was left, with its older pages, without reading it again
|
|
// (Services/FeedMemory.cs).
|
|
public sealed class FeedMemoryTests(Browser browser)
|
|
{
|
|
[Fact]
|
|
public async Task The_feed_comes_back_from_a_thread_as_it_was_left()
|
|
{
|
|
var persona = Pasture.Personas().First();
|
|
await using var session = await SignIn.As(browser, persona);
|
|
var page = session.Page;
|
|
// a deletion the stream tells (late federated Deletes from the tests before) takes its post out at once
|
|
var deletions = 0;
|
|
page.WebSocket += (_, socket) => socket.FrameReceived += (_, frame) =>
|
|
{
|
|
if (frame.Text?.Contains("\"event\":\"delete\"") == true)
|
|
Interlocked.Increment(ref deletions);
|
|
};
|
|
await Results.Cell("client.action.feed-memory", "privapub", persona.UserName, async () =>
|
|
{
|
|
await page.GotoAsync($"{Pasture.Site}/");
|
|
await page.EvaluateAsync("() => localStorage.removeItem('FeedFilter')");
|
|
await page.GotoAsync($"{Pasture.Site}/");
|
|
var feed = page.Locator("[data-feed-count]");
|
|
await page.Locator("article[data-uri]").First.WaitForAsync(new() { Timeout = 30000 });
|
|
// an older page too when there is one, so there is more to keep than the first
|
|
await page.EvalOnSelectorAsync("#feed-scroll", "root => root.scrollTop = root.scrollHeight");
|
|
await Pasture.Eventually(async () => int.Parse(await feed.GetAttributeAsync("data-feed-count") ?? "0") > 20, 10);
|
|
var count = int.Parse(await feed.GetAttributeAsync("data-feed-count") ?? "0");
|
|
var deletedBefore = Volatile.Read(ref deletions);
|
|
|
|
var homeReads = 0;
|
|
page.Request += (_, request) =>
|
|
{
|
|
if (request.Url.Contains("/api/v1/timelines/home") && !request.Url.Contains("min_id"))
|
|
homeReads++;
|
|
};
|
|
await page.EvalOnSelectorAsync("#feed-scroll", "root => root.scrollTop = 0");
|
|
await page.Locator("article[data-uri] footer a[title='Expand']").First.ClickAsync();
|
|
await page.WaitForURLAsync("**/expand/**");
|
|
await page.GoBackAsync();
|
|
await page.Locator("article[data-uri]").First.WaitForAsync(new() { Timeout = 10000 });
|
|
|
|
var back = int.Parse(await feed.GetAttributeAsync("data-feed-count") ?? "0");
|
|
var deleted = Volatile.Read(ref deletions) - deletedBefore;
|
|
Assert.True(back >= count - deleted, $"the feed came back with {back} posts, left with {count} ({deleted} deleted meanwhile)");
|
|
Assert.Equal(0, homeReads);
|
|
await session.AssertGuards();
|
|
}, page);
|
|
}
|
|
}
|
|
}
|