1
0
mirror of https://github.com/ppy/osu.git synced 2024-11-11 20:59:35 +08:00
osu-lazer/osu.Game.Tests/Visual/Online/TestSceneChatOverlay.cs

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

701 lines
30 KiB
C#
Raw Normal View History

// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
2022-06-17 15:37:17 +08:00
#nullable disable
using System;
using System.Linq;
using System.Collections.Generic;
using System.Net;
using System.Threading;
using JetBrains.Annotations;
using NUnit.Framework;
using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Input;
using osu.Framework.Logging;
using osu.Framework.Testing;
using osu.Framework.Utils;
using osu.Game.Configuration;
using osu.Game.Graphics.UserInterface;
using osu.Game.Online.API;
using osu.Game.Online.API.Requests;
using osu.Game.Online.API.Requests.Responses;
using osu.Game.Online.Chat;
using osu.Game.Overlays;
using osu.Game.Overlays.Chat;
using osu.Game.Overlays.Chat.Listing;
using osu.Game.Overlays.Chat.ChannelList;
using osuTK;
using osuTK.Input;
namespace osu.Game.Tests.Visual.Online
{
[TestFixture]
public partial class TestSceneChatOverlay : OsuManualInputManagerTestScene
{
private TestChatOverlay chatOverlay;
private ChannelManager channelManager;
private readonly APIUser testUser = new APIUser { Username = "test user", Id = 5071479 };
2022-11-02 16:00:47 +08:00
private readonly APIUser testUser1 = new APIUser { Username = "test user", Id = 5071480 };
private Channel[] testChannels;
private Message[] initialMessages;
private Channel testChannel1 => testChannels[0];
private Channel testChannel2 => testChannels[1];
[Resolved]
private OsuConfigManager config { get; set; } = null!;
private int currentMessageId;
[SetUp]
public void SetUp() => Schedule(() =>
{
currentMessageId = 0;
testChannels = Enumerable.Range(1, 10).Select(createPublicChannel).ToArray();
initialMessages = testChannels.SelectMany(createChannelMessages).ToArray();
Child = new DependencyProvidingContainer
{
RelativeSizeAxes = Axes.Both,
CachedDependencies = new (Type, object)[]
{
(typeof(ChannelManager), channelManager = new ChannelManager(API)),
},
Children = new Drawable[]
{
channelManager,
chatOverlay = new TestChatOverlay(),
},
};
});
[SetUpSteps]
public void SetUpSteps()
{
AddStep("Setup request handler", () =>
{
((DummyAPIAccess)API).HandleRequest = req =>
{
switch (req)
{
case CreateChannelRequest createRequest:
createRequest.TriggerSuccess(new APIChatChannel
{
ChannelID = ((int)createRequest.Channel.Id),
RecentMessages = new List<Message>()
});
return true;
case GetUpdatesRequest getUpdates:
getUpdates.TriggerFailure(new WebException());
return true;
case JoinChannelRequest joinChannel:
joinChannel.TriggerSuccess();
return true;
case LeaveChannelRequest leaveChannel:
leaveChannel.TriggerSuccess();
return true;
case GetMessagesRequest getMessages:
getMessages.TriggerSuccess(initialMessages.ToList());
return true;
case GetUserRequest getUser:
if (getUser.Lookup == testUser.Username)
getUser.TriggerSuccess(testUser);
else
getUser.TriggerFailure(new WebException());
return true;
case PostMessageRequest postMessage:
postMessage.TriggerSuccess(new Message(RNG.Next(0, 10000000))
{
Content = postMessage.Message.Content,
ChannelId = postMessage.Message.ChannelId,
Sender = postMessage.Message.Sender,
Timestamp = new DateTimeOffset(DateTime.Now),
});
return true;
default:
Logger.Log($"Unhandled Request Type: {req.GetType()}");
return false;
}
};
});
AddStep("Add test channels", () =>
{
(channelManager.AvailableChannels as BindableList<Channel>)?.AddRange(testChannels);
});
}
[Test]
public void TestBasic()
{
AddStep("Show overlay with channel", () =>
{
chatOverlay.Show();
Channel joinedChannel = channelManager.JoinChannel(testChannel1);
channelManager.CurrentChannel.Value = joinedChannel;
});
AddAssert("Overlay is visible", () => chatOverlay.State.Value == Visibility.Visible);
waitForChannel1Visible();
}
[Test]
public void TestShowHide()
{
AddStep("Show overlay", () => chatOverlay.Show());
AddAssert("Overlay is visible", () => chatOverlay.State.Value == Visibility.Visible);
AddStep("Hide overlay", () => chatOverlay.Hide());
AddAssert("Overlay is hidden", () => chatOverlay.State.Value == Visibility.Hidden);
}
[Test]
public void TestChatHeight()
{
BindableFloat configChatHeight = new BindableFloat();
2022-05-29 21:55:53 +08:00
float newHeight = 0;
2022-05-29 21:55:53 +08:00
AddStep("Reset config chat height", () =>
{
config.BindWith(OsuSetting.ChatDisplayHeight, configChatHeight);
configChatHeight.SetDefault();
});
AddStep("Show overlay", () => chatOverlay.Show());
AddAssert("Overlay uses config height", () => chatOverlay.Height == configChatHeight.Default);
AddStep("Click top bar", () =>
2022-05-05 21:52:03 +08:00
{
InputManager.MoveMouseTo(chatOverlayTopBar);
InputManager.PressButton(MouseButton.Left);
});
AddStep("Drag overlay to new height", () => InputManager.MoveMouseTo(chatOverlayTopBar, new Vector2(0, -300)));
AddStep("Stop dragging", () => InputManager.ReleaseButton(MouseButton.Left));
AddStep("Store new height", () => newHeight = chatOverlay.Height);
AddAssert("Config height changed", () => !configChatHeight.IsDefault && configChatHeight.Value == newHeight);
AddStep("Hide overlay", () => chatOverlay.Hide());
AddStep("Show overlay", () => chatOverlay.Show());
AddAssert("Overlay uses new height", () => chatOverlay.Height == newHeight);
}
[Test]
public void TestChannelSelection()
{
AddStep("Show overlay", () => chatOverlay.Show());
AddAssert("Listing is visible", () => listingIsVisible);
joinTestChannel(0);
AddStep("Select channel 1", () => clickDrawable(getChannelListItem(testChannel1)));
waitForChannel1Visible();
}
[Test]
public void TestSearchInListing()
{
AddStep("Show overlay", () => chatOverlay.Show());
AddAssert("Listing is visible", () => listingIsVisible);
AddStep("Search for 'number 2'", () => chatOverlayTextBox.Text = "number 2");
AddUntilStep("Only channel 2 visible", () =>
{
IEnumerable<ChannelListingItem> listingItems = chatOverlay.ChildrenOfType<ChannelListingItem>()
.Where(item => item.IsPresent);
return listingItems.Count() == 1 && listingItems.Single().Channel == testChannel2;
});
}
[Test]
public void TestChannelCloseButton()
{
var testPMChannel = new Channel(testUser);
AddStep("Show overlay", () => chatOverlay.Show());
joinTestChannel(0);
joinChannel(testPMChannel);
AddStep("Select PM channel", () => clickDrawable(getChannelListItem(testPMChannel)));
AddStep("Click close button", () =>
{
ChannelListItemCloseButton closeButton = getChannelListItem(testPMChannel).ChildrenOfType<ChannelListItemCloseButton>().Single();
clickDrawable(closeButton);
});
AddAssert("PM channel closed", () => !channelManager.JoinedChannels.Contains(testPMChannel));
AddStep("Select normal channel", () => clickDrawable(getChannelListItem(testChannel1)));
AddStep("Click close button", () =>
{
ChannelListItemCloseButton closeButton = getChannelListItem(testChannel1).ChildrenOfType<ChannelListItemCloseButton>().Single();
clickDrawable(closeButton);
});
AddAssert("Normal channel closed", () => !channelManager.JoinedChannels.Contains(testChannel1));
}
[Test]
public void TestChatCommand()
{
AddStep("Show overlay", () => chatOverlay.Show());
joinTestChannel(0);
AddStep("Select channel 1", () => clickDrawable(getChannelListItem(testChannel1)));
AddStep("Open chat with user", () => channelManager.PostCommand($"chat {testUser.Username}"));
AddAssert("PM channel is selected", () =>
channelManager.CurrentChannel.Value.Type == ChannelType.PM && channelManager.CurrentChannel.Value.Users.Single() == testUser);
AddStep("Open chat with non-existent user", () => channelManager.PostCommand("chat user_doesnt_exist"));
AddAssert("Last message is error", () => channelManager.CurrentChannel.Value.Messages.Last() is ErrorMessage);
// Make sure no unnecessary requests are made when the PM channel is already open.
AddStep("Select channel 1", () => clickDrawable(getChannelListItem(testChannel1)));
AddStep("Unregister request handling", () => ((DummyAPIAccess)API).HandleRequest = null);
AddStep("Open chat with user", () => channelManager.PostCommand($"chat {testUser.Username}"));
AddAssert("PM channel is selected", () =>
channelManager.CurrentChannel.Value.Type == ChannelType.PM && channelManager.CurrentChannel.Value.Users.Single() == testUser);
}
[Test]
public void TestMultiplayerChannelIsNotShown()
{
Channel multiplayerChannel;
AddStep("Show overlay", () => chatOverlay.Show());
joinChannel(multiplayerChannel = new Channel(new APIUser())
{
Name = "#mp_1",
Type = ChannelType.Multiplayer,
});
AddAssert("Channel is joined", () => channelManager.JoinedChannels.Contains(multiplayerChannel));
AddUntilStep("Channel not present in listing", () => !chatOverlay.ChildrenOfType<ChannelListingItem>()
.Where(item => item.IsPresent)
.Select(item => item.Channel)
.Contains(multiplayerChannel));
}
[Test]
public void TestHighlightOnCurrentChannel()
{
Message message = null;
AddStep("Show overlay", () => chatOverlay.Show());
joinTestChannel(0);
AddStep("Select channel 1", () => clickDrawable(getChannelListItem(testChannel1)));
AddStep("Send message in channel 1", () =>
{
testChannel1.AddNewMessages(message = new Message
{
ChannelId = testChannel1.Id,
Content = "Message to highlight!",
Timestamp = DateTimeOffset.Now,
Sender = testUser,
});
});
AddStep("Highlight message", () => chatOverlay.HighlightMessage(message, testChannel1));
waitForChannel1Visible();
}
[Test]
public void TestHighlightOnAnotherChannel()
{
Message message = null;
AddStep("Show overlay", () => chatOverlay.Show());
joinTestChannel(0);
joinTestChannel(1);
AddStep("Select channel 1", () => clickDrawable(getChannelListItem(testChannel1)));
AddStep("Send message in channel 2", () =>
{
testChannel2.AddNewMessages(message = new Message
{
ChannelId = testChannel2.Id,
Content = "Message to highlight!",
Timestamp = DateTimeOffset.Now,
Sender = testUser,
});
});
AddStep("Highlight message", () => chatOverlay.HighlightMessage(message, testChannel2));
waitForChannel2Visible();
}
[Test]
public void TestHighlightOnLeftChannel()
{
Message message = null;
AddStep("Show overlay", () => chatOverlay.Show());
joinTestChannel(0);
joinTestChannel(1);
AddStep("Select channel 1", () => clickDrawable(getChannelListItem(testChannel1)));
AddStep("Send message in channel 2", () =>
{
testChannel2.AddNewMessages(message = new Message
{
ChannelId = testChannel2.Id,
Content = "Message to highlight!",
Timestamp = DateTimeOffset.Now,
Sender = testUser,
});
});
AddStep("Leave channel 2", () => channelManager.LeaveChannel(testChannel2));
AddStep("Highlight message", () => chatOverlay.HighlightMessage(message, testChannel2));
waitForChannel2Visible();
}
[Test]
public void TestHighlightWhileChatNeverOpen()
{
Message message = null;
joinTestChannel(0);
AddStep("Send message in channel 1", () =>
{
testChannel1.AddNewMessages(message = new Message
{
ChannelId = testChannel1.Id,
Content = "Message to highlight!",
Timestamp = DateTimeOffset.Now,
Sender = testUser,
});
});
AddStep("Highlight message", () => chatOverlay.HighlightMessage(message, testChannel1));
waitForChannel1Visible();
}
[Test]
public void TestHighlightWithNullChannel()
{
Message message = null;
joinTestChannel(0);
AddStep("Send message in channel 1", () =>
{
testChannel1.AddNewMessages(message = new Message
{
ChannelId = testChannel1.Id,
Content = "Message to highlight!",
Timestamp = DateTimeOffset.Now,
Sender = testUser,
});
});
AddStep("Set null channel", () => channelManager.CurrentChannel.Value = null);
AddStep("Highlight message", () => chatOverlay.HighlightMessage(message, testChannel1));
waitForChannel1Visible();
}
[Test]
public void TestTextBoxRetainsFocus()
{
AddStep("Show overlay", () => chatOverlay.Show());
AddAssert("TextBox is focused", () => InputManager.FocusedDrawable == chatOverlayTextBox);
joinTestChannel(0);
AddStep("Select channel 1", () => clickDrawable(getChannelListItem(testChannel1)));
waitForChannel1Visible();
AddAssert("TextBox is focused", () => InputManager.FocusedDrawable == chatOverlayTextBox);
AddStep("Click drawable channel", () => clickDrawable(currentDrawableChannel));
AddAssert("TextBox is focused", () => InputManager.FocusedDrawable == chatOverlayTextBox);
AddStep("Click selector", () => clickDrawable(channelSelectorButton));
AddAssert("TextBox is focused", () => InputManager.FocusedDrawable == chatOverlayTextBox);
AddStep("Click listing", () => clickDrawable(chatOverlay.ChildrenOfType<ChannelListing>().Single()));
AddAssert("TextBox is focused", () => InputManager.FocusedDrawable == chatOverlayTextBox);
AddStep("Click channel list", () => clickDrawable(chatOverlay.ChildrenOfType<ChannelList>().Single()));
AddAssert("TextBox is focused", () => InputManager.FocusedDrawable == chatOverlayTextBox);
AddStep("Click top bar", () => clickDrawable(chatOverlay.ChildrenOfType<ChatOverlayTopBar>().Single()));
AddAssert("TextBox is focused", () => InputManager.FocusedDrawable == chatOverlayTextBox);
AddStep("Hide overlay", () => chatOverlay.Hide());
AddAssert("TextBox is not focused", () => InputManager.FocusedDrawable == null);
}
[Test]
public void TestSlowLoadingChannel()
{
AddStep("Show overlay (slow-loading)", () =>
{
chatOverlay.Show();
chatOverlay.SlowLoading = true;
});
joinTestChannel(0);
2022-05-22 00:35:31 +08:00
AddStep("Select channel 1", () => clickDrawable(getChannelListItem(testChannel1)));
Fix some more chat tests failing intermittently ``` TearDown : osu.Framework.Testing.Drawables.Steps.AssertButton+TracedException : Channel 1 ready --TearDown at osu.Framework.Threading.ScheduledDelegate.RunTaskInternal() at osu.Framework.Threading.Scheduler.Update() at osu.Framework.Graphics.Drawable.UpdateSubTree() at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree() at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree() at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree() at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree() at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree() at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree() at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree() at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree() at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree() at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree() at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree() at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree() at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree() at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree() at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree() at osu.Framework.Platform.GameHost.UpdateFrame() at osu.Framework.Threading.GameThread.processFrame() at osu.Framework.Threading.GameThread.RunSingleFrame() at osu.Framework.Threading.GameThread.<createThread>g__runWork|66_0() at System.Threading.Thread.StartHelper.Callback(Object state) at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state) ----- One or more child tests had errors Exception doesn't have a stacktrace [runtime] 2022-05-29 19:29:09 [verbose]: 💨 Class: TestSceneChatOverlayV2 [runtime] 2022-05-29 19:29:09 [verbose]: 🔶 Test: TestSlowLoadingChannel [runtime] 2022-05-29 19:29:09 [verbose]: Chat is now polling every 60000 ms [runtime] 2022-05-29 19:29:09 [verbose]: 🔸 Step #1 Setup request handler [runtime] 2022-05-29 19:29:09 [verbose]: 🔸 Step #2 Add test channels [runtime] 2022-05-29 19:29:09 [verbose]: 🔸 Step #3 Show overlay (slow-loading) [runtime] 2022-05-29 19:29:09 [verbose]: 🔸 Step #4 Join channel 1 [runtime] 2022-05-29 19:29:09 [verbose]: 🔸 Step #5 Select channel 1 [runtime] 2022-05-29 19:29:09 [verbose]: 🔸 Step #6 Channel 1 loading [runtime] 2022-05-29 19:29:09 [verbose]: 🔸 Step #7 Join channel 2 [runtime] 2022-05-29 19:29:09 [verbose]: 🔸 Step #8 Select channel 2 [runtime] 2022-05-29 19:29:09 [verbose]: 🔸 Step #9 Channel 2 loading [runtime] 2022-05-29 19:29:09 [verbose]: 🔸 Step #10 Finish channel 1 load [runtime] 2022-05-29 19:29:09 [verbose]: 🔸 Step #11 Channel 1 ready [runtime] 2022-05-29 19:29:09 [verbose]: 💥 Failed [runtime] 2022-05-29 19:29:09 [verbose]: ⏳ Currently loading components (2) [runtime] 2022-05-29 19:29:09 [verbose]: TestSceneChatOverlayV2+SlowLoadingDrawableChannel [runtime] 2022-05-29 19:29:09 [verbose]: - thread: ThreadedTaskScheduler (LoadComponentsAsync (standard)) [runtime] 2022-05-29 19:29:09 [verbose]: - state: Loading [runtime] 2022-05-29 19:29:09 [verbose]: TestSceneChatOverlayV2+SlowLoadingDrawableChannel [runtime] 2022-05-29 19:29:09 [verbose]: - thread: ThreadedTaskScheduler (LoadComponentsAsync (standard)) [runtime] 2022-05-29 19:29:09 [verbose]: - state: Ready [runtime] 2022-05-29 19:29:09 [verbose]: 🧵 Task schedulers [runtime] 2022-05-29 19:29:09 [verbose]: LoadComponentsAsync (standard) concurrency:4 running:1 pending:0 [runtime] 2022-05-29 19:29:09 [verbose]: LoadComponentsAsync (long load) concurrency:4 running:0 pending:0 [runtime] 2022-05-29 19:29:09 [verbose]: 🎱 Thread pool [runtime] 2022-05-29 19:29:09 [verbose]: worker: min 32 max 32,767 available 32,765 [runtime] 2022-05-29 19:29:09 [verbose]: completion: min 32 max 1,000 available 1,000 ```
2022-05-30 03:34:08 +08:00
AddUntilStep("Channel 1 loading", () => !channelIsVisible && chatOverlay.GetSlowLoadingChannel(testChannel1).LoadState == LoadState.Loading);
joinTestChannel(1);
AddStep("Select channel 2", () => clickDrawable(getChannelListItem(testChannel2)));
Fix some more chat tests failing intermittently ``` TearDown : osu.Framework.Testing.Drawables.Steps.AssertButton+TracedException : Channel 1 ready --TearDown at osu.Framework.Threading.ScheduledDelegate.RunTaskInternal() at osu.Framework.Threading.Scheduler.Update() at osu.Framework.Graphics.Drawable.UpdateSubTree() at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree() at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree() at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree() at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree() at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree() at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree() at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree() at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree() at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree() at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree() at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree() at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree() at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree() at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree() at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree() at osu.Framework.Platform.GameHost.UpdateFrame() at osu.Framework.Threading.GameThread.processFrame() at osu.Framework.Threading.GameThread.RunSingleFrame() at osu.Framework.Threading.GameThread.<createThread>g__runWork|66_0() at System.Threading.Thread.StartHelper.Callback(Object state) at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state) ----- One or more child tests had errors Exception doesn't have a stacktrace [runtime] 2022-05-29 19:29:09 [verbose]: 💨 Class: TestSceneChatOverlayV2 [runtime] 2022-05-29 19:29:09 [verbose]: 🔶 Test: TestSlowLoadingChannel [runtime] 2022-05-29 19:29:09 [verbose]: Chat is now polling every 60000 ms [runtime] 2022-05-29 19:29:09 [verbose]: 🔸 Step #1 Setup request handler [runtime] 2022-05-29 19:29:09 [verbose]: 🔸 Step #2 Add test channels [runtime] 2022-05-29 19:29:09 [verbose]: 🔸 Step #3 Show overlay (slow-loading) [runtime] 2022-05-29 19:29:09 [verbose]: 🔸 Step #4 Join channel 1 [runtime] 2022-05-29 19:29:09 [verbose]: 🔸 Step #5 Select channel 1 [runtime] 2022-05-29 19:29:09 [verbose]: 🔸 Step #6 Channel 1 loading [runtime] 2022-05-29 19:29:09 [verbose]: 🔸 Step #7 Join channel 2 [runtime] 2022-05-29 19:29:09 [verbose]: 🔸 Step #8 Select channel 2 [runtime] 2022-05-29 19:29:09 [verbose]: 🔸 Step #9 Channel 2 loading [runtime] 2022-05-29 19:29:09 [verbose]: 🔸 Step #10 Finish channel 1 load [runtime] 2022-05-29 19:29:09 [verbose]: 🔸 Step #11 Channel 1 ready [runtime] 2022-05-29 19:29:09 [verbose]: 💥 Failed [runtime] 2022-05-29 19:29:09 [verbose]: ⏳ Currently loading components (2) [runtime] 2022-05-29 19:29:09 [verbose]: TestSceneChatOverlayV2+SlowLoadingDrawableChannel [runtime] 2022-05-29 19:29:09 [verbose]: - thread: ThreadedTaskScheduler (LoadComponentsAsync (standard)) [runtime] 2022-05-29 19:29:09 [verbose]: - state: Loading [runtime] 2022-05-29 19:29:09 [verbose]: TestSceneChatOverlayV2+SlowLoadingDrawableChannel [runtime] 2022-05-29 19:29:09 [verbose]: - thread: ThreadedTaskScheduler (LoadComponentsAsync (standard)) [runtime] 2022-05-29 19:29:09 [verbose]: - state: Ready [runtime] 2022-05-29 19:29:09 [verbose]: 🧵 Task schedulers [runtime] 2022-05-29 19:29:09 [verbose]: LoadComponentsAsync (standard) concurrency:4 running:1 pending:0 [runtime] 2022-05-29 19:29:09 [verbose]: LoadComponentsAsync (long load) concurrency:4 running:0 pending:0 [runtime] 2022-05-29 19:29:09 [verbose]: 🎱 Thread pool [runtime] 2022-05-29 19:29:09 [verbose]: worker: min 32 max 32,767 available 32,765 [runtime] 2022-05-29 19:29:09 [verbose]: completion: min 32 max 1,000 available 1,000 ```
2022-05-30 03:34:08 +08:00
AddUntilStep("Channel 2 loading", () => !channelIsVisible && chatOverlay.GetSlowLoadingChannel(testChannel2).LoadState == LoadState.Loading);
AddStep("Finish channel 1 load", () => chatOverlay.GetSlowLoadingChannel(testChannel1).LoadEvent.Set());
Fix some more chat tests failing intermittently ``` TearDown : osu.Framework.Testing.Drawables.Steps.AssertButton+TracedException : Channel 1 ready --TearDown at osu.Framework.Threading.ScheduledDelegate.RunTaskInternal() at osu.Framework.Threading.Scheduler.Update() at osu.Framework.Graphics.Drawable.UpdateSubTree() at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree() at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree() at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree() at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree() at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree() at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree() at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree() at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree() at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree() at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree() at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree() at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree() at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree() at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree() at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree() at osu.Framework.Platform.GameHost.UpdateFrame() at osu.Framework.Threading.GameThread.processFrame() at osu.Framework.Threading.GameThread.RunSingleFrame() at osu.Framework.Threading.GameThread.<createThread>g__runWork|66_0() at System.Threading.Thread.StartHelper.Callback(Object state) at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state) ----- One or more child tests had errors Exception doesn't have a stacktrace [runtime] 2022-05-29 19:29:09 [verbose]: 💨 Class: TestSceneChatOverlayV2 [runtime] 2022-05-29 19:29:09 [verbose]: 🔶 Test: TestSlowLoadingChannel [runtime] 2022-05-29 19:29:09 [verbose]: Chat is now polling every 60000 ms [runtime] 2022-05-29 19:29:09 [verbose]: 🔸 Step #1 Setup request handler [runtime] 2022-05-29 19:29:09 [verbose]: 🔸 Step #2 Add test channels [runtime] 2022-05-29 19:29:09 [verbose]: 🔸 Step #3 Show overlay (slow-loading) [runtime] 2022-05-29 19:29:09 [verbose]: 🔸 Step #4 Join channel 1 [runtime] 2022-05-29 19:29:09 [verbose]: 🔸 Step #5 Select channel 1 [runtime] 2022-05-29 19:29:09 [verbose]: 🔸 Step #6 Channel 1 loading [runtime] 2022-05-29 19:29:09 [verbose]: 🔸 Step #7 Join channel 2 [runtime] 2022-05-29 19:29:09 [verbose]: 🔸 Step #8 Select channel 2 [runtime] 2022-05-29 19:29:09 [verbose]: 🔸 Step #9 Channel 2 loading [runtime] 2022-05-29 19:29:09 [verbose]: 🔸 Step #10 Finish channel 1 load [runtime] 2022-05-29 19:29:09 [verbose]: 🔸 Step #11 Channel 1 ready [runtime] 2022-05-29 19:29:09 [verbose]: 💥 Failed [runtime] 2022-05-29 19:29:09 [verbose]: ⏳ Currently loading components (2) [runtime] 2022-05-29 19:29:09 [verbose]: TestSceneChatOverlayV2+SlowLoadingDrawableChannel [runtime] 2022-05-29 19:29:09 [verbose]: - thread: ThreadedTaskScheduler (LoadComponentsAsync (standard)) [runtime] 2022-05-29 19:29:09 [verbose]: - state: Loading [runtime] 2022-05-29 19:29:09 [verbose]: TestSceneChatOverlayV2+SlowLoadingDrawableChannel [runtime] 2022-05-29 19:29:09 [verbose]: - thread: ThreadedTaskScheduler (LoadComponentsAsync (standard)) [runtime] 2022-05-29 19:29:09 [verbose]: - state: Ready [runtime] 2022-05-29 19:29:09 [verbose]: 🧵 Task schedulers [runtime] 2022-05-29 19:29:09 [verbose]: LoadComponentsAsync (standard) concurrency:4 running:1 pending:0 [runtime] 2022-05-29 19:29:09 [verbose]: LoadComponentsAsync (long load) concurrency:4 running:0 pending:0 [runtime] 2022-05-29 19:29:09 [verbose]: 🎱 Thread pool [runtime] 2022-05-29 19:29:09 [verbose]: worker: min 32 max 32,767 available 32,765 [runtime] 2022-05-29 19:29:09 [verbose]: completion: min 32 max 1,000 available 1,000 ```
2022-05-30 03:34:08 +08:00
AddUntilStep("Channel 1 ready", () => chatOverlay.GetSlowLoadingChannel(testChannel1).LoadState == LoadState.Ready);
AddAssert("Channel 1 not displayed", () => !channelIsVisible);
AddStep("Finish channel 2 load", () => chatOverlay.GetSlowLoadingChannel(testChannel2).LoadEvent.Set());
Fix some more chat tests failing intermittently ``` TearDown : osu.Framework.Testing.Drawables.Steps.AssertButton+TracedException : Channel 1 ready --TearDown at osu.Framework.Threading.ScheduledDelegate.RunTaskInternal() at osu.Framework.Threading.Scheduler.Update() at osu.Framework.Graphics.Drawable.UpdateSubTree() at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree() at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree() at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree() at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree() at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree() at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree() at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree() at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree() at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree() at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree() at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree() at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree() at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree() at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree() at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree() at osu.Framework.Platform.GameHost.UpdateFrame() at osu.Framework.Threading.GameThread.processFrame() at osu.Framework.Threading.GameThread.RunSingleFrame() at osu.Framework.Threading.GameThread.<createThread>g__runWork|66_0() at System.Threading.Thread.StartHelper.Callback(Object state) at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state) ----- One or more child tests had errors Exception doesn't have a stacktrace [runtime] 2022-05-29 19:29:09 [verbose]: 💨 Class: TestSceneChatOverlayV2 [runtime] 2022-05-29 19:29:09 [verbose]: 🔶 Test: TestSlowLoadingChannel [runtime] 2022-05-29 19:29:09 [verbose]: Chat is now polling every 60000 ms [runtime] 2022-05-29 19:29:09 [verbose]: 🔸 Step #1 Setup request handler [runtime] 2022-05-29 19:29:09 [verbose]: 🔸 Step #2 Add test channels [runtime] 2022-05-29 19:29:09 [verbose]: 🔸 Step #3 Show overlay (slow-loading) [runtime] 2022-05-29 19:29:09 [verbose]: 🔸 Step #4 Join channel 1 [runtime] 2022-05-29 19:29:09 [verbose]: 🔸 Step #5 Select channel 1 [runtime] 2022-05-29 19:29:09 [verbose]: 🔸 Step #6 Channel 1 loading [runtime] 2022-05-29 19:29:09 [verbose]: 🔸 Step #7 Join channel 2 [runtime] 2022-05-29 19:29:09 [verbose]: 🔸 Step #8 Select channel 2 [runtime] 2022-05-29 19:29:09 [verbose]: 🔸 Step #9 Channel 2 loading [runtime] 2022-05-29 19:29:09 [verbose]: 🔸 Step #10 Finish channel 1 load [runtime] 2022-05-29 19:29:09 [verbose]: 🔸 Step #11 Channel 1 ready [runtime] 2022-05-29 19:29:09 [verbose]: 💥 Failed [runtime] 2022-05-29 19:29:09 [verbose]: ⏳ Currently loading components (2) [runtime] 2022-05-29 19:29:09 [verbose]: TestSceneChatOverlayV2+SlowLoadingDrawableChannel [runtime] 2022-05-29 19:29:09 [verbose]: - thread: ThreadedTaskScheduler (LoadComponentsAsync (standard)) [runtime] 2022-05-29 19:29:09 [verbose]: - state: Loading [runtime] 2022-05-29 19:29:09 [verbose]: TestSceneChatOverlayV2+SlowLoadingDrawableChannel [runtime] 2022-05-29 19:29:09 [verbose]: - thread: ThreadedTaskScheduler (LoadComponentsAsync (standard)) [runtime] 2022-05-29 19:29:09 [verbose]: - state: Ready [runtime] 2022-05-29 19:29:09 [verbose]: 🧵 Task schedulers [runtime] 2022-05-29 19:29:09 [verbose]: LoadComponentsAsync (standard) concurrency:4 running:1 pending:0 [runtime] 2022-05-29 19:29:09 [verbose]: LoadComponentsAsync (long load) concurrency:4 running:0 pending:0 [runtime] 2022-05-29 19:29:09 [verbose]: 🎱 Thread pool [runtime] 2022-05-29 19:29:09 [verbose]: worker: min 32 max 32,767 available 32,765 [runtime] 2022-05-29 19:29:09 [verbose]: completion: min 32 max 1,000 available 1,000 ```
2022-05-30 03:34:08 +08:00
AddUntilStep("Channel 2 loaded", () => chatOverlay.GetSlowLoadingChannel(testChannel2).IsLoaded);
waitForChannel2Visible();
AddStep("Select channel 1", () => clickDrawable(getChannelListItem(testChannel1)));
Fix some more chat tests failing intermittently ``` TearDown : osu.Framework.Testing.Drawables.Steps.AssertButton+TracedException : Channel 1 ready --TearDown at osu.Framework.Threading.ScheduledDelegate.RunTaskInternal() at osu.Framework.Threading.Scheduler.Update() at osu.Framework.Graphics.Drawable.UpdateSubTree() at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree() at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree() at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree() at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree() at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree() at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree() at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree() at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree() at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree() at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree() at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree() at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree() at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree() at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree() at osu.Framework.Graphics.Containers.CompositeDrawable.UpdateSubTree() at osu.Framework.Platform.GameHost.UpdateFrame() at osu.Framework.Threading.GameThread.processFrame() at osu.Framework.Threading.GameThread.RunSingleFrame() at osu.Framework.Threading.GameThread.<createThread>g__runWork|66_0() at System.Threading.Thread.StartHelper.Callback(Object state) at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state) ----- One or more child tests had errors Exception doesn't have a stacktrace [runtime] 2022-05-29 19:29:09 [verbose]: 💨 Class: TestSceneChatOverlayV2 [runtime] 2022-05-29 19:29:09 [verbose]: 🔶 Test: TestSlowLoadingChannel [runtime] 2022-05-29 19:29:09 [verbose]: Chat is now polling every 60000 ms [runtime] 2022-05-29 19:29:09 [verbose]: 🔸 Step #1 Setup request handler [runtime] 2022-05-29 19:29:09 [verbose]: 🔸 Step #2 Add test channels [runtime] 2022-05-29 19:29:09 [verbose]: 🔸 Step #3 Show overlay (slow-loading) [runtime] 2022-05-29 19:29:09 [verbose]: 🔸 Step #4 Join channel 1 [runtime] 2022-05-29 19:29:09 [verbose]: 🔸 Step #5 Select channel 1 [runtime] 2022-05-29 19:29:09 [verbose]: 🔸 Step #6 Channel 1 loading [runtime] 2022-05-29 19:29:09 [verbose]: 🔸 Step #7 Join channel 2 [runtime] 2022-05-29 19:29:09 [verbose]: 🔸 Step #8 Select channel 2 [runtime] 2022-05-29 19:29:09 [verbose]: 🔸 Step #9 Channel 2 loading [runtime] 2022-05-29 19:29:09 [verbose]: 🔸 Step #10 Finish channel 1 load [runtime] 2022-05-29 19:29:09 [verbose]: 🔸 Step #11 Channel 1 ready [runtime] 2022-05-29 19:29:09 [verbose]: 💥 Failed [runtime] 2022-05-29 19:29:09 [verbose]: ⏳ Currently loading components (2) [runtime] 2022-05-29 19:29:09 [verbose]: TestSceneChatOverlayV2+SlowLoadingDrawableChannel [runtime] 2022-05-29 19:29:09 [verbose]: - thread: ThreadedTaskScheduler (LoadComponentsAsync (standard)) [runtime] 2022-05-29 19:29:09 [verbose]: - state: Loading [runtime] 2022-05-29 19:29:09 [verbose]: TestSceneChatOverlayV2+SlowLoadingDrawableChannel [runtime] 2022-05-29 19:29:09 [verbose]: - thread: ThreadedTaskScheduler (LoadComponentsAsync (standard)) [runtime] 2022-05-29 19:29:09 [verbose]: - state: Ready [runtime] 2022-05-29 19:29:09 [verbose]: 🧵 Task schedulers [runtime] 2022-05-29 19:29:09 [verbose]: LoadComponentsAsync (standard) concurrency:4 running:1 pending:0 [runtime] 2022-05-29 19:29:09 [verbose]: LoadComponentsAsync (long load) concurrency:4 running:0 pending:0 [runtime] 2022-05-29 19:29:09 [verbose]: 🎱 Thread pool [runtime] 2022-05-29 19:29:09 [verbose]: worker: min 32 max 32,767 available 32,765 [runtime] 2022-05-29 19:29:09 [verbose]: completion: min 32 max 1,000 available 1,000 ```
2022-05-30 03:34:08 +08:00
AddUntilStep("Channel 1 loaded", () => chatOverlay.GetSlowLoadingChannel(testChannel1).IsLoaded);
waitForChannel1Visible();
}
[Test]
public void TestKeyboardCloseAndRestoreChannel()
{
AddStep("Show overlay with channel 1", () =>
{
channelManager.JoinChannel(testChannel1);
chatOverlay.Show();
});
waitForChannel1Visible();
AddStep("Press document close keys", () => InputManager.Keys(PlatformAction.DocumentClose));
AddAssert("Listing is visible", () => listingIsVisible);
AddStep("Press tab restore keys", () => InputManager.Keys(PlatformAction.TabRestore));
waitForChannel1Visible();
}
[Test]
public void TestKeyboardNewChannel()
{
AddStep("Show overlay with channel 1", () =>
{
channelManager.JoinChannel(testChannel1);
chatOverlay.Show();
});
waitForChannel1Visible();
AddStep("Press tab new keys", () => InputManager.Keys(PlatformAction.TabNew));
AddAssert("Listing is visible", () => listingIsVisible);
}
[Test]
public void TestKeyboardNextChannel()
{
Channel announceChannel = createAnnounceChannel();
Channel pmChannel1 = createPrivateChannel();
Channel pmChannel2 = createPrivateChannel();
joinTestChannel(0);
joinTestChannel(1);
joinChannel(pmChannel1);
joinChannel(pmChannel2);
joinChannel(announceChannel);
AddStep("Show overlay", () => chatOverlay.Show());
AddStep("Select channel 1", () => clickDrawable(getChannelListItem(testChannel1)));
waitForChannel1Visible();
Add logging around current channel changes and join requests Tracking down a flaky test (https://teamcity.ppy.sh/buildConfiguration/Osu_Build/553?hideProblemsFromDependencies=false&expandBuildTestsSection=true&hideTestsFromDependencies=false): ```csharp TearDown : System.TimeoutException : "PM Channel 1 displayed" timed out --TearDown at osu.Framework.Testing.Drawables.Steps.UntilStepButton.<>c__DisplayClass11_0.<.ctor>b__0() at osu.Framework.Testing.Drawables.Steps.StepButton.PerformStep(Boolean userTriggered) at osu.Framework.Testing.TestScene.runNextStep(Action onCompletion, Action`1 onError, Func`2 stopCondition) --- End of stack trace from previous location --- at osu.Framework.Testing.TestSceneTestRunner.TestRunner.RunTestBlocking(TestScene test) at osu.Game.Tests.Visual.OsuTestScene.OsuTestSceneTestRunner.RunTestBlocking(TestScene test) in /opt/buildagent/work/ecd860037212ac52/osu.Game/Tests/Visual/OsuTestScene.cs:line 503 at osu.Framework.Testing.TestScene.RunTestsFromNUnit() ------- Stdout: ------- [runtime] 2022-06-27 23:18:55 [verbose]: 💨 Class: TestSceneChatOverlay [runtime] 2022-06-27 23:18:55 [verbose]: 🔶 Test: TestKeyboardNextChannel [runtime] 2022-06-27 23:18:55 [verbose]: Chat is now polling every 60000 ms [runtime] 2022-06-27 23:18:55 [verbose]: 🔸 Step #1 Setup request handler [runtime] 2022-06-27 23:18:55 [verbose]: 🔸 Step #2 Add test channels [runtime] 2022-06-27 23:18:55 [verbose]: 🔸 Step #3 Show overlay with channels [runtime] 2022-06-27 23:18:55 [verbose]: Unhandled Request Type: osu.Game.Online.API.Requests.CreateChannelRequest [network] 2022-06-27 23:18:55 [verbose]: Failing request osu.Game.Online.API.Requests.CreateChannelRequest (System.InvalidOperationException: DummyAPIAccess cannot process this request.) [runtime] 2022-06-27 23:18:55 [verbose]: Unhandled Request Type: osu.Game.Online.API.Requests.CreateChannelRequest [network] 2022-06-27 23:18:55 [verbose]: Failing request osu.Game.Online.API.Requests.CreateChannelRequest (System.InvalidOperationException: DummyAPIAccess cannot process this request.) [runtime] 2022-06-27 23:18:55 [verbose]: 🔸 Step #4 Select channel 1 [runtime] 2022-06-27 23:18:55 [verbose]: 🔸 Step #5 Channel 1 is visible [runtime] 2022-06-27 23:18:55 [verbose]: 🔸 Step #6 Press document next keys [runtime] 2022-06-27 23:18:55 [verbose]: 🔸 Step #7 Channel 2 is visible [runtime] 2022-06-27 23:18:55 [verbose]: 🔸 Step #8 Press document next keys [runtime] 2022-06-27 23:18:55 [verbose]: 🔸 Step #9 PM Channel 1 displayed [network] 2022-06-27 23:18:55 [verbose]: Request to https://a.ppy.sh/587 failed with System.Net.WebException: NotFound. [network] 2022-06-27 23:18:55 [verbose]: Request to https://a.ppy.sh/503 failed with System.Net.WebException: NotFound. [runtime] 2022-06-27 23:19:05 [verbose]: 💥 Failed (on attempt 5,550) [runtime] 2022-06-27 23:19:05 [verbose]: ⏳ Currently loading components (0) [runtime] 2022-06-27 23:19:05 [verbose]: 🧵 Task schedulers [runtime] 2022-06-27 23:19:05 [verbose]: LoadComponentsAsync (standard) concurrency:4 running:0 pending:0 [runtime] 2022-06-27 23:19:05 [verbose]: LoadComponentsAsync (long load) concurrency:4 running:0 pending:0 [runtime] 2022-06-27 23:19:05 [verbose]: 🎱 Thread pool [runtime] 2022-06-27 23:19:05 [verbose]: worker: min 1 max 32,767 available 32,766 [runtime] 2022-06-27 23:19:05 [verbose]: completion: min 1 max 1,000 available 1,000 [runtime] 2022-06-27 23:19:05 [debug]: Focus on "ChatTextBox" no longer valid as a result of unfocusIfNoLongerValid. [runtime] 2022-06-27 23:19:05 [debug]: Focus changed from ChatTextBox to nothing. ``` This kind of logging should be helpful: ```csharp [runtime] 2022-06-28 04:59:57 [verbose]: 🔸 Step #5 Channel 1 is visible [runtime] 2022-06-28 04:59:57 [verbose]: 🔸 Step #6 Press document next keys [runtime] 2022-06-28 04:59:57 [verbose]: Current channel changed to #channel-2 [runtime] 2022-06-28 04:59:57 [debug]: Pressed (DocumentNext) handled by TestSceneChatOverlay+TestChatOverlay. [runtime] 2022-06-28 04:59:57 [debug]: KeyDownEvent(PageDown, False) handled by ManualInputManager+LocalPlatformActionContainer. [runtime] 2022-06-28 04:59:57 [verbose]: 🔸 Step #7 Channel 2 is visible [runtime] 2022-06-28 04:59:57 [verbose]: 🔸 Step #8 Press document next keys [runtime] 2022-06-28 04:59:57 [verbose]: Current channel changed to test user 685 [runtime] 2022-06-28 04:59:57 [debug]: Pressed (DocumentNext) handled by TestSceneChatOverlay+TestChatOverlay. [runtime] 2022-06-28 04:59:57 [debug]: KeyDownEvent(PageDown, False) handled by ManualInputManager+LocalPlatformActionContainer. [runtime] 2022-06-28 04:59:57 [verbose]: 🔸 Step #9 PM Channel 1 displayed [runtime] 2022-06-28 04:59:57 [verbose]: 🔸 Step #10 Press document next keys [runtime] 2022-06-28 04:59:57 [verbose]: Current channel changed to test user 218 ```
2022-06-28 12:58:35 +08:00
AddStep("Press document next keys", () => InputManager.Keys(PlatformAction.DocumentNext));
waitForChannel2Visible();
AddStep("Press document next keys", () => InputManager.Keys(PlatformAction.DocumentNext));
AddUntilStep("PM Channel 1 displayed", () => channelIsVisible && currentDrawableChannel?.Channel == pmChannel1);
AddStep("Press document next keys", () => InputManager.Keys(PlatformAction.DocumentNext));
AddUntilStep("PM Channel 2 displayed", () => channelIsVisible && currentDrawableChannel?.Channel == pmChannel2);
AddStep("Press document next keys", () => InputManager.Keys(PlatformAction.DocumentNext));
AddUntilStep("Announce channel displayed", () => channelIsVisible && currentDrawableChannel?.Channel == announceChannel);
AddStep("Press document next keys", () => InputManager.Keys(PlatformAction.DocumentNext));
waitForChannel1Visible();
}
2022-11-02 16:00:47 +08:00
[Test]
public void TestRemoveMessages()
{
AddStep("Show overlay with channel", () =>
{
chatOverlay.Show();
channelManager.CurrentChannel.Value = channelManager.JoinChannel(testChannel1);
});
AddAssert("Overlay is visible", () => chatOverlay.State.Value == Visibility.Visible);
waitForChannel1Visible();
AddStep("Send message from another user", () =>
{
testChannel1.AddNewMessages(new Message
{
ChannelId = testChannel1.Id,
Content = "Message from another user",
Timestamp = DateTimeOffset.Now,
Sender = testUser1,
});
});
AddStep("Remove messages from other user", () =>
{
testChannel1.RemoveMessagesFromUser(testUser.Id);
});
}
[Test]
public void TestTextBoxSavePerChannel()
{
var testPMChannel = new Channel(testUser);
AddStep("show overlay", () => chatOverlay.Show());
joinTestChannel(0);
joinChannel(testPMChannel);
AddAssert("listing is visible", () => listingIsVisible);
AddStep("search for 'number 2'", () => chatOverlayTextBox.Text = "number 2");
AddAssert("'number 2' saved to selector", () => channelManager.CurrentChannel.Value.TextBoxMessage.Value == "number 2");
AddStep("select normal channel", () => clickDrawable(getChannelListItem(testChannel1)));
AddAssert("text box cleared on normal channel", () => chatOverlayTextBox.Text == string.Empty);
AddAssert("nothing saved on normal channel", () => channelManager.CurrentChannel.Value.TextBoxMessage.Value == string.Empty);
AddStep("type '727'", () => chatOverlayTextBox.Text = "727");
AddAssert("'727' saved to normal channel", () => channelManager.CurrentChannel.Value.TextBoxMessage.Value == "727");
AddStep("select PM channel", () => clickDrawable(getChannelListItem(testPMChannel)));
AddAssert("text box cleared on PM channel", () => chatOverlayTextBox.Text == string.Empty);
AddAssert("nothing saved on PM channel", () => channelManager.CurrentChannel.Value.TextBoxMessage.Value == string.Empty);
AddStep("type 'hello'", () => chatOverlayTextBox.Text = "hello");
AddAssert("'hello' saved to PM channel", () => channelManager.CurrentChannel.Value.TextBoxMessage.Value == "hello");
AddStep("select normal channel", () => clickDrawable(getChannelListItem(testChannel1)));
AddAssert("text box contains '727'", () => chatOverlayTextBox.Text == "727");
AddStep("select PM channel", () => clickDrawable(getChannelListItem(testPMChannel)));
AddAssert("text box contains 'hello'", () => chatOverlayTextBox.Text == "hello");
AddStep("click close button", () =>
{
ChannelListItemCloseButton closeButton = getChannelListItem(testPMChannel).ChildrenOfType<ChannelListItemCloseButton>().Single();
clickDrawable(closeButton);
});
AddAssert("listing is visible", () => listingIsVisible);
AddAssert("text box contains 'channel 2'", () => chatOverlayTextBox.Text == "number 2");
AddUntilStep("only channel 2 visible", () =>
{
IEnumerable<ChannelListingItem> listingItems = chatOverlay.ChildrenOfType<ChannelListingItem>()
.Where(item => item.IsPresent);
return listingItems.Count() == 1 && listingItems.Single().Channel == testChannel2;
});
}
private void joinTestChannel(int i)
{
AddStep($"Join test channel {i}", () => channelManager.JoinChannel(testChannels[i]));
AddUntilStep("wait for join completed", () => testChannels[i].Joined.Value);
}
private void joinChannel(Channel channel)
{
AddStep($"Join channel {channel}", () => channelManager.JoinChannel(channel));
AddUntilStep("wait for join completed", () => channel.Joined.Value);
}
private void waitForChannel1Visible() =>
AddUntilStep("Channel 1 is visible", () => channelIsVisible && currentDrawableChannel?.Channel == testChannel1);
private void waitForChannel2Visible() =>
AddUntilStep("Channel 2 is visible", () => channelIsVisible && currentDrawableChannel?.Channel == testChannel2);
private bool listingIsVisible =>
chatOverlay.ChildrenOfType<ChannelListing>().Single().State.Value == Visibility.Visible;
private bool loadingIsVisible =>
chatOverlay.ChildrenOfType<LoadingLayer>().Single().State.Value == Visibility.Visible;
private bool channelIsVisible =>
!listingIsVisible && !loadingIsVisible;
[CanBeNull]
private DrawableChannel currentDrawableChannel =>
chatOverlay.ChildrenOfType<DrawableChannel>().SingleOrDefault();
private ChannelListItem getChannelListItem(Channel channel) =>
chatOverlay.ChildrenOfType<ChannelListItem>().Single(item => item.Channel == channel);
private ChatTextBox chatOverlayTextBox =>
chatOverlay.ChildrenOfType<ChatTextBox>().Single();
private ChatOverlayTopBar chatOverlayTopBar =>
chatOverlay.ChildrenOfType<ChatOverlayTopBar>().Single();
private ChannelListItem channelSelectorButton =>
chatOverlay.ChildrenOfType<ChannelListItem>().Single(item => item.Channel is ChannelListing.ChannelListingChannel);
private void clickDrawable(Drawable d)
{
InputManager.MoveMouseTo(d);
InputManager.Click(MouseButton.Left);
}
private List<Message> createChannelMessages(Channel channel)
{
var message = new Message(currentMessageId++)
{
ChannelId = channel.Id,
Content = $"Hello, this is a message in {channel.Name}",
Sender = testUser,
Timestamp = new DateTimeOffset(DateTime.Now),
};
return new List<Message> { message };
}
private Channel createPublicChannel(int id) => new Channel
{
Id = id,
Name = $"#channel-{id}",
Topic = $"We talk about the number {id} here",
Type = ChannelType.Public,
};
private Channel createPrivateChannel()
{
int id = RNG.Next(0, DummyAPIAccess.DUMMY_USER_ID - 1);
return new Channel(new APIUser
{
Id = id,
Username = $"test user {id}",
});
}
private Channel createAnnounceChannel()
{
const int announce_channel_id = 133337;
return new Channel
{
Name = $"Announce {announce_channel_id}",
Type = ChannelType.Announce,
Id = announce_channel_id,
};
}
private partial class TestChatOverlay : ChatOverlay
{
public bool SlowLoading { get; set; }
public SlowLoadingDrawableChannel GetSlowLoadingChannel(Channel channel) => DrawableChannels.OfType<SlowLoadingDrawableChannel>().Single(c => c.Channel == channel);
protected override DrawableChannel CreateDrawableChannel(Channel newChannel)
{
return SlowLoading
? new SlowLoadingDrawableChannel(newChannel)
: new DrawableChannel(newChannel);
}
}
private partial class SlowLoadingDrawableChannel : DrawableChannel
{
public readonly ManualResetEventSlim LoadEvent = new ManualResetEventSlim();
public SlowLoadingDrawableChannel([NotNull] Channel channel)
: base(channel)
{
}
[BackgroundDependencyLoader]
private void load()
{
LoadEvent.Wait(10000);
}
}
}
}