Skip to content

Commit ee21144

Browse files
committed
WIP #309 - Add test coverage and fix some issues
1 parent de55905 commit ee21144

19 files changed

Lines changed: 345 additions & 30 deletions

CSF.Screenplay.Selenium/Actions/BeginCollectingLogsWithJavaScript.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ namespace CSF.Screenplay.Selenium.Actions
2222
/// performance (wasted network roundtrips).
2323
/// </para>
2424
/// <para>
25-
/// This action is for use only with web browsers which have the <see cref="BrowserQuirks.RequiresJavascriptToGetLogs"/> quirk.
25+
/// This action is for use only with web browsers which have the <see cref="BrowserQuirks.CanGetLogsWithJavascriptWorkaround"/> quirk.
2626
/// </para>
2727
/// </remarks>
2828
public class BeginCollectingLogsWithJavaScript : IPerformable, ICanReport
@@ -35,7 +35,7 @@ public ReportFragment GetReportFragment(Actor actor, IFormatsReportFragment form
3535
public async ValueTask PerformAsAsync(ICanPerform actor, CancellationToken cancellationToken = default)
3636
{
3737
var driver = actor.GetAbility<BrowseTheWeb>();
38-
if(!driver.WebDriver.HasQuirk(BrowserQuirks.RequiresJavascriptToGetLogs))
38+
if(!driver.WebDriver.HasQuirk(BrowserQuirks.CanGetLogsWithJavascriptWorkaround))
3939
throw new NotSupportedException("The WebDriver must have support for retrieving logs using a Javascript workaround.");
4040

4141
await actor.PerformAsync(PerformableBuilder.ExecuteAScript(Scripts.CaptureLogs), cancellationToken);

CSF.Screenplay.Selenium/Actions/OpenUrl.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ public async ValueTask PerformAsAsync(ICanPerform actor, CancellationToken cance
5656
throw new InvalidOperationException($"The URL to open must be absolute; have you forgotten to grant {actor} the {nameof(UseABaseUri)} ability?");
5757
ability.WebDriver.Url = uri.Uri.ToString();
5858

59-
if(ability.ShouldCollectLogs && ability.WebDriver.HasQuirk(BrowserQuirks.RequiresJavascriptToGetLogs))
59+
if(ability.ShouldCollectLogs && ability.WebDriver.HasQuirk(BrowserQuirks.CanGetLogsWithJavascriptWorkaround))
6060
await actor.PerformAsync(BeginCollectingLogsWithJavaScript(), cancellationToken);
6161
}
6262

CSF.Screenplay.Selenium/BrowseTheWeb.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ public class BrowseTheWeb : ICanReport, IDisposable
9999
/// <para>
100100
/// When this value is set to <see langword="true"/>, this will trigger usage of <see cref="Actions.BeginCollectingLogsWithJavaScript"/>
101101
/// at points where it is required. This is applicable only when the current <see cref="WebDriver"/> implementation has the
102-
/// quirk <see cref="BrowserQuirks.RequiresJavascriptToGetLogs"/>.
102+
/// quirk <see cref="BrowserQuirks.CanGetLogsWithJavascriptWorkaround"/>.
103103
/// </para>
104104
/// </remarks>
105105
public bool ShouldCollectLogs => collectLogs;

CSF.Screenplay.Selenium/BrowserQuirks.cs

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -113,17 +113,17 @@ public static class BrowserQuirks
113113
public static readonly string HasNativeLogsSupport = "HasNativeLogsSupport";
114114

115115
/// <summary>
116-
/// Gets the name of a browser quirk, for browsers which can read browser logs, but which require a Javascript-based workaround.
116+
/// Gets the name of a browser quirk, for browsers which can read browser logs using a Javascript-based workaround.
117117
/// </summary>
118118
/// <remarks>
119119
/// <para>
120-
/// Browsers with this quirk cannot read logs in the way that those which <see cref="HasNativeLogsSupport"/> can, however JavaScript
121-
/// may be used to intercept logs as they are sent to the console. These may then be stored and retrieved with a different script.
120+
/// Browsers with this quirk should prefer using the techniques provided by <see cref="HasNativeLogsSupport"/> if they also support them.
121+
/// The use of a Javascript workaround is imperfect and can miss log messages, as described in the documentation for <see cref="GetLogsWithJavaScript"/>.
122122
/// </para>
123123
/// </remarks>
124124
/// <seealso cref="Scripts.CaptureLogs"/>
125125
/// <seealso cref="Scripts.GetLogs"/>
126-
public static readonly string RequiresJavascriptToGetLogs = "RequiresJavascriptToGetLogs";
126+
public static readonly string CanGetLogsWithJavascriptWorkaround = "CanGetLogsWithJavascriptWorkaround";
127127

128128
/// <summary>
129129
/// Gets hard-coded information about known browser quirks.
@@ -198,12 +198,14 @@ public static QuirksData GetQuirksData()
198198
}
199199
},
200200
{
201-
RequiresJavascriptToGetLogs,
201+
CanGetLogsWithJavascriptWorkaround,
202202
new BrowserInfoCollection
203203
{
204204
AffectedBrowsers = new HashSet<BrowserInfo>
205205
{
206206
new BrowserInfo { Name = firefox },
207+
new BrowserInfo { Name = chrome },
208+
new BrowserInfo { Name = edge },
207209
}
208210
}
209211
}

CSF.Screenplay.Selenium/Builders/GetTheBrowserLogsBuilder.cs

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
using System.Collections.Generic;
2+
using CSF.Screenplay.Performables;
3+
using CSF.Screenplay.Selenium.Questions;
14
using CSF.Screenplay.Selenium.Tasks;
25

36
namespace CSF.Screenplay.Selenium.Builders
@@ -11,7 +14,7 @@ namespace CSF.Screenplay.Selenium.Builders
1114
/// collection, should retrieving logs be unsupported by the current WebDriver.
1215
/// </para>
1316
/// </remarks>
14-
public class GetTheBrowserLogsBuilder
17+
public class GetTheBrowserLogsBuilder : IGetsPerformableWithResult<IReadOnlyList<BrowserLog>>
1518
{
1619
/// <summary>
1720
/// Gets a <see cref="GetTheBrowserLogs"/> task.
@@ -22,11 +25,7 @@ public class GetTheBrowserLogsBuilder
2225
public GetTheBrowserLogs ButReturnEmptyLogsIfUnsupported()
2326
=> new GetTheBrowserLogs(false);
2427

25-
/// <summary>
26-
/// Implicitly converts the builder to an instance of <see cref="GetTheBrowserLogs"/>.
27-
/// The task will throw if no viable technique for getting logs is available.
28-
/// </summary>
29-
public static implicit operator GetTheBrowserLogs(GetTheBrowserLogsBuilder _)
28+
IPerformableWithResult<IReadOnlyList<BrowserLog>> IGetsPerformableWithResult<IReadOnlyList<BrowserLog>>.GetPerformable()
3029
=> new GetTheBrowserLogs();
3130
}
3231
}

CSF.Screenplay.Selenium/CSF.Screenplay.Selenium.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232

3333
<ItemGroup>
3434
<EmbeddedResource Include="**\*.restext" />
35+
<EmbeddedResource Include="Resources\**\*.js" />
3536
</ItemGroup>
3637

3738
</Project>

CSF.Screenplay.Selenium/PerformableBuilder.general.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -216,7 +216,7 @@ public static NamedWaitBuilder WaitUntil(IBuildsElementPredicates predicate)
216216
/// <para>
217217
/// It is usually not required to use this action directly.
218218
/// The recommended way to consume this action is to set <see cref="BrowseTheWeb.ShouldCollectLogs"/> to <see langword="true"/>
219-
/// via the ability's constructor. If the WebDriver has the quirk <see cref="BrowserQuirks.RequiresJavascriptToGetLogs"/> then
219+
/// via the ability's constructor. If the WebDriver has the quirk <see cref="BrowserQuirks.CanGetLogsWithJavascriptWorkaround"/> then
220220
/// this action will be executed automatically at appropriate times, such as immediately after <see cref="ClickAndWaitForDocumentReady"/>
221221
/// or <see cref="OpenUrl"/> is executed.
222222
/// </para>

CSF.Screenplay.Selenium/Questions/BrowserLog.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,5 +36,8 @@ public sealed class BrowserLog
3636
/// Gets the timestamp at which the log message was recorded.
3737
/// </summary>
3838
public DateTime Timestamp { get; set; }
39+
40+
/// <inheritdoc/>
41+
public override string ToString() => $"{Timestamp:s} [{Level}]: {Message}";
3942
}
4043
}

CSF.Screenplay.Selenium/Questions/GetLogsWithJavaScript.cs

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,13 @@ namespace CSF.Screenplay.Selenium.Questions
2626
/// not missing any messages.
2727
/// </para>
2828
/// <para>
29-
/// This action is for use only with web browsers which have the <see cref="BrowserQuirks.RequiresJavascriptToGetLogs"/> quirk.
29+
/// This action is for use only with web browsers which have the <see cref="BrowserQuirks.CanGetLogsWithJavascriptWorkaround"/> quirk.
30+
/// </para>
31+
/// <para>
32+
/// Note that this question will not (and cannot) respect the WebDriver's logging preference, such as set at
33+
/// <see cref="Extensions.WebDriver.Factories.WebDriverCreationOptions.BrowserLogLevel"/> or
34+
/// <see cref="DriverOptions.SetLoggingPreference(string, LogLevel)"/>.
35+
/// Consumers will need to manually filter for messages which they care about, based upon the log level.
3036
/// </para>
3137
/// </remarks>
3238
public class GetLogsWithJavaScript : IPerformableWithResult<IReadOnlyList<BrowserLog>>, ICanReport
@@ -39,12 +45,13 @@ public ReportFragment GetReportFragment(Actor actor, IFormatsReportFragment form
3945
public async ValueTask<IReadOnlyList<BrowserLog>> PerformAsAsync(ICanPerform actor, CancellationToken cancellationToken = default)
4046
{
4147
var driver = actor.GetAbility<BrowseTheWeb>();
42-
if(!driver.WebDriver.HasQuirk(BrowserQuirks.RequiresJavascriptToGetLogs))
48+
if(!driver.WebDriver.HasQuirk(BrowserQuirks.CanGetLogsWithJavascriptWorkaround))
4349
throw new NotSupportedException("The WebDriver must have support for retrieving logs using a Javascript workaround.");
4450

4551
var result = await actor.PerformAsync(PerformableBuilder.ExecuteAScript(Scripts.GetLogs), cancellationToken);
4652
return result
47-
.Select(x => new BrowserLog { Level = x["Level"].ToString(), Message = x["Message"].ToString(), Timestamp = (DateTime) x["Timestamp"] })
53+
.Cast<IDictionary<string,object>>()
54+
.Select(x => new BrowserLog { Level = x["Level"].ToString(), Message = x["Message"].ToString(), Timestamp = DateTime.Parse((string) x["Timestamp"]) })
4855
.ToArray();
4956
}
5057
}

CSF.Screenplay.Selenium/Resources/GetLogs.js

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,9 @@ return function() {
44
const logs = globalThis['__csfScreenplayLogs'].messages.filter(x => !x.Consumed);
55
for(const log of logs)
66
log.Consumed = true;
7-
return logs;
7+
return logs.map(x => ({
8+
Level: x.Level,
9+
Message: x.Message.toString(),
10+
Timestamp: x.Timestamp.toISOString()
11+
}));
812
}();

0 commit comments

Comments
 (0)