Skip to content

Commit

Permalink
Execute in scope with error handling
Browse files Browse the repository at this point in the history
  • Loading branch information
nvborisenko committed Apr 27, 2024
1 parent a301a82 commit 8c69aff
Show file tree
Hide file tree
Showing 16 changed files with 253 additions and 106 deletions.
2 changes: 1 addition & 1 deletion Yapoml.Playwright.sln
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Yapoml.Playwright.Sample",
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Yapoml.Playwright", "src\Yapoml.Playwright\Yapoml.Playwright.csproj", "{95C372C4-6BC3-4F29-B92E-FF71F1D74369}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Yapoml.Playwright.SourceGeneration", "src\Yapoml.Playwright.SourceGeneration\Yapoml.Playwright.SourceGeneration.csproj", "{8DEAB4F2-8951-4B94-81E5-537CE4E65DE7}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Yapoml.Playwright.SourceGeneration", "src\Yapoml.Playwright.SourceGeneration\Yapoml.Playwright.SourceGeneration.csproj", "{8DEAB4F2-8951-4B94-81E5-537CE4E65DE7}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,12 @@ partial class Conditions<TSelf>
{
public TSelf IsNotWhite()
{
using (this.Logger.BeginLogScope($"Expect {this.ElementHandler.ComponentMetadata.Name} color is not white"))
using var logScope = Logger.BeginLogScope($"Expect {this.ElementHandler.ComponentMetadata.Name} color is not white");

return logScope.Execute(() =>
{
return Styles.BackgroundColor.DoesNotContain("255, 255, 255");
}
});
}
}
}
Expand Down
6 changes: 4 additions & 2 deletions sample/Yapoml.Playwright.Sample/Home.page.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,15 @@ public partial class HomePage
{
public PackagesPage Search(string text)
{
using (_logger.BeginLogScope($"Searching for packages by '{text}' query"))
using var scope = _logger.BeginLogScope($"Searching for packages by '{text}' query");

return scope.Execute(() =>
{
SearchInput.Fill(text);
SearchButton.Click();

return SpaceOptions.Services.Get<YaSpace>().PackagesPage;
}
});
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -249,9 +249,12 @@ public partial class {{$1.singular_name}}ComponentList : global::Yapoml.Playwrig
/// </summary>
public {{$1.singular_name}}ComponentList Expect(global::System.Action<Conditions> it)
{
using (_logger.BeginLogScope($"Expect {_elementsListHandler.ComponentsListMetadata.Name} satisfy conditions"))
using (var scope = _logger.BeginLogScope($"Expect {_elementsListHandler.ComponentsListMetadata.Name} satisfy conditions"))
{
it(listConditions);
scope.Execute(() =>
{
it(listConditions);
});
}

return this;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,14 @@ public partial class Conditions : global::Yapoml.Playwright.Components.BasePageC
/// </summary>
public override Conditions IsOpened(global::System.TimeSpan? timeout = default)
{
using (Logger.BeginLogScope("Expect the {{$1.name}} page is opened"))
using (var scope = Logger.BeginLogScope("Expect the {{$1.name}} page is opened"))
{
Url.Contains("{{ $1.url.path }}", timeout);
return scope.Execute(() =>
{
Url.Contains("{{ $1.url.path }}", timeout);

return base.IsOpened(timeout);
return base.IsOpened(timeout);
});
}
}
{{ end }}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,14 @@ public class OneTimeConditions : global::Yapoml.Playwright.Components.BasePageCo
/// </summary>
public override {{get_page_class_name $1}} IsOpened(global::System.TimeSpan? timeout = default)
{
using (Logger.BeginLogScope("Expect the {{$1.name}} page is opened"))
using (var scope = Logger.BeginLogScope("Expect the {{$1.name}} page is opened"))
{
Url.Contains("{{ $1.url.path }}", timeout);
return scope.Execute(() =>
{
Url.Contains("{{ $1.url.path }}", timeout);

return base.IsOpened(timeout);
return base.IsOpened(timeout);
});
}
}
{{ end }}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,14 @@ namespace {{namespace}}

EventSource.PageEventSource.RaiseOnPageNavigating(this, url, Metadata);

using (_logger.BeginLogScope($"Opening {Metadata.Name} page by {url}"))
using (var scope = _logger.BeginLogScope($"Opening {Metadata.Name} page by {url}"))
{
Driver.GotoAsync(url.ToString()).GetAwaiter().GetResult();
scope.Execute(async () =>
{
await Driver.GotoAsync(url.ToString());
});
}

return this;
}
{{ end }}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
<PackageReference Include="Microsoft.CodeAnalysis.Analyzers" Version="3.3.3" PrivateAssets="all" />
<PackageReference Include="Scriban" Version="5.9.0" GeneratePathProperty="true" PrivateAssets="all" />
<PackageReference Include="YamlDotNet" Version="13.4.0" GeneratePathProperty="true" PrivateAssets="all" />
<PackageReference Include="Yapoml.Framework.Workspace" Version="0.13.1" GeneratePathProperty="true" PrivateAssets="all" />
<PackageReference Include="Yapoml.Framework.Workspace" Version="0.14.1" GeneratePathProperty="true" PrivateAssets="all" />
</ItemGroup>

<ItemGroup>
Expand Down
111 changes: 78 additions & 33 deletions src/Yapoml.Playwright/Components/BaseComponent.Actions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,12 @@ partial class BaseComponent<TComponent, TConditions, TCondition>
/// <returns>The same instance of the component to continue interaction with it.</returns>
public virtual TComponent Clear()
{
using (_logger.BeginLogScope($"Clearing {Metadata.Name}"))
using (var scope = _logger.BeginLogScope($"Clearing {Metadata.Name}"))
{
RelocateOnStaleReference(() => WrappedElement.ClearAsync().GetAwaiter().GetResult());
scope.Execute(() =>
{
RelocateOnStaleReference(() => WrappedElement.ClearAsync().GetAwaiter().GetResult());
});
}

return component;
Expand Down Expand Up @@ -54,9 +57,12 @@ public virtual TComponent Type(string text)
scopeName = $"Typing '{text}' into {Metadata.Name}";
}

using (_logger.BeginLogScope(scopeName))
using (var scope = _logger.BeginLogScope(scopeName))
{
RelocateOnStaleReference(() => WrappedElement.TypeAsync(text).GetAwaiter().GetResult());
scope.Execute(async () =>
{
await RelocateOnStaleReference(async () => await WrappedElement.TypeAsync(text));

Check warning on line 64 in src/Yapoml.Playwright/Components/BaseComponent.Actions.cs

View workflow job for this annotation

GitHub Actions / build

'ILocator.TypeAsync(string, LocatorTypeOptions?)' is obsolete

Check warning on line 64 in src/Yapoml.Playwright/Components/BaseComponent.Actions.cs

View workflow job for this annotation

GitHub Actions / build

'ILocator.TypeAsync(string, LocatorTypeOptions?)' is obsolete

Check warning on line 64 in src/Yapoml.Playwright/Components/BaseComponent.Actions.cs

View workflow job for this annotation

GitHub Actions / build

'ILocator.TypeAsync(string, LocatorTypeOptions?)' is obsolete

Check warning on line 64 in src/Yapoml.Playwright/Components/BaseComponent.Actions.cs

View workflow job for this annotation

GitHub Actions / build

'ILocator.TypeAsync(string, LocatorTypeOptions?)' is obsolete

Check warning on line 64 in src/Yapoml.Playwright/Components/BaseComponent.Actions.cs

View workflow job for this annotation

GitHub Actions / build

'ILocator.TypeAsync(string, LocatorTypeOptions?)' is obsolete

Check warning on line 64 in src/Yapoml.Playwright/Components/BaseComponent.Actions.cs

View workflow job for this annotation

GitHub Actions / build

'ILocator.TypeAsync(string, LocatorTypeOptions?)' is obsolete

Check warning on line 64 in src/Yapoml.Playwright/Components/BaseComponent.Actions.cs

View workflow job for this annotation

GitHub Actions / build

'ILocator.TypeAsync(string, LocatorTypeOptions?)' is obsolete
});
}

return component;
Expand All @@ -78,9 +84,12 @@ public virtual TComponent Type(string text, Action<TConditions> when)
/// <returns>The same instance of the component to continue interaction with it.</returns>
public virtual TComponent Fill(string text)
{
using (_logger.BeginLogScope($"Filling in {component.Metadata.Name} within '{text}'"))
using (var scope = _logger.BeginLogScope($"Filling in {component.Metadata.Name} within '{text}'"))
{
RelocateOnStaleReference(() => WrappedElement.FillAsync(text).GetAwaiter().GetResult());
scope.Execute(() =>
{
RelocateOnStaleReference(() => WrappedElement.FillAsync(text).GetAwaiter().GetResult());
});
}

return component;
Expand All @@ -102,9 +111,12 @@ public virtual TComponent Fill(string text, Action<TConditions> when)
/// <returns>The same instance of the component to continue interaction with it.</returns>
public virtual TComponent Click()
{
using (_logger.BeginLogScope($"Clicking on {Metadata.Name}"))
using (var scope = _logger.BeginLogScope($"Clicking on {Metadata.Name}"))
{
RelocateOnStaleReference(() => WrappedElement.ClickAsync().GetAwaiter().GetResult());
scope.Execute(async () =>
{
await RelocateOnStaleReference(async () => await WrappedElement.ClickAsync());
});
}

return component;
Expand All @@ -124,9 +136,12 @@ public virtual TComponent Click(Action<TConditions> when)
/// <param name="y">Coordinates offset by Y-axis.</param>
public virtual TComponent Click(int x, int y)
{
using (_logger.BeginLogScope($"Clicking on {Metadata.Name} by X: {x}, Y: {y}"))
using (var scope = _logger.BeginLogScope($"Clicking on {Metadata.Name} by X: {x}, Y: {y}"))
{
RelocateOnStaleReference(() => WrappedElement.ClickAsync(new Microsoft.Playwright.LocatorClickOptions { Position = new Microsoft.Playwright.Position { X = x, Y = y } }).GetAwaiter().GetResult());
scope.Execute(async () =>
{
await RelocateOnStaleReference(async () => await WrappedElement.ClickAsync(new Microsoft.Playwright.LocatorClickOptions { Position = new Microsoft.Playwright.Position { X = x, Y = y } }));
});
}

return component;
Expand All @@ -151,9 +166,12 @@ public virtual TComponent Click(int x, int y, Action<TConditions> when)
/// <returns>The same instance of the component to continue interaction with it.</returns>
public virtual TComponent Hover()
{
using (_logger.BeginLogScope($"Hovering over {Metadata.Name}"))
using (var scope = _logger.BeginLogScope($"Hovering over {Metadata.Name}"))
{
RelocateOnStaleReference(() => WrappedElement.HoverAsync().GetAwaiter().GetResult());
scope.Execute(async () =>
{
await RelocateOnStaleReference(async () => await WrappedElement.HoverAsync());
});
}

return component;
Expand All @@ -173,10 +191,13 @@ public virtual TComponent Hover(Action<TConditions> when)
/// <param name="y">Coordinates offset by Y-axis.</param>
public virtual TComponent Hover(int x, int y)
{
using (_logger.BeginLogScope($"Hovering on {Metadata.Name} by X: {x}, Y: {y}"))
using (var scope = _logger.BeginLogScope($"Hovering on {Metadata.Name} by X: {x}, Y: {y}"))
{
RelocateOnStaleReference(() => WrappedElement.HoverAsync(new Microsoft.Playwright.LocatorHoverOptions { Position = new Microsoft.Playwright.Position { X = x, Y = y } }).GetAwaiter().GetResult());
}
scope.Execute(async () =>
{
await RelocateOnStaleReference(async () => await WrappedElement.HoverAsync(new Microsoft.Playwright.LocatorHoverOptions { Position = new Microsoft.Playwright.Position { X = x, Y = y } }));
});
};

return component;
}
Expand Down Expand Up @@ -206,9 +227,12 @@ public virtual TComponent ScrollIntoView()
}
else
{
using (_logger.BeginLogScope($"Scrolling {Metadata.Name} into view"))
using (var scope = _logger.BeginLogScope($"Scrolling {Metadata.Name} into view"))
{
RelocateOnStaleReference(() => WrappedElement.ScrollIntoViewIfNeededAsync().GetAwaiter().GetResult());
scope.Execute(async () =>
{
await RelocateOnStaleReference(async () => await WrappedElement.ScrollIntoViewIfNeededAsync());
});
}
}

Expand Down Expand Up @@ -239,9 +263,12 @@ public virtual TComponent ScrollIntoView(ScrollIntoViewOptions options)
{
if (options == null) throw new ArgumentNullException(nameof(options));

using (_logger.BeginLogScope($"Scrolling {Metadata.Name} into view with options {options}"))
using (var scope = _logger.BeginLogScope($"Scrolling {Metadata.Name} into view with options {options}"))
{
RelocateOnStaleReference(() => WrappedElement.ScrollIntoViewIfNeededAsync().GetAwaiter().GetResult());
scope.Execute(async () =>
{
await RelocateOnStaleReference(async () => await WrappedElement.ScrollIntoViewIfNeededAsync());
});
}

return component;
Expand Down Expand Up @@ -272,9 +299,12 @@ public virtual TComponent Focus()
}
else
{
using (_logger.BeginLogScope($"Focusing {Metadata.Name}"))
using (var scope = _logger.BeginLogScope($"Focusing {Metadata.Name}"))
{
RelocateOnStaleReference(() => WrappedElement.FocusAsync().GetAwaiter().GetResult());
scope.Execute(async () =>
{
await RelocateOnStaleReference(async () => await WrappedElement.FocusAsync());
});
}
}

Expand Down Expand Up @@ -303,9 +333,12 @@ public virtual TComponent Focus(FocusOptions options)
{
if (options == null) throw new ArgumentNullException(nameof(options));

using (_logger.BeginLogScope($"Focusing {Metadata.Name} with options {options}"))
using (var scope = _logger.BeginLogScope($"Focusing {Metadata.Name} with options {options}"))
{
RelocateOnStaleReference(() => WrappedElement.FocusAsync());
scope.Execute(async () =>
{
await RelocateOnStaleReference(async () => await WrappedElement.FocusAsync());
});
}

return component;
Expand All @@ -330,9 +363,12 @@ public virtual TComponent Focus(FocusOptions options, Action<TConditions> when)
/// <returns>The same instance of the component to continue interaction with it.</returns>
public virtual TComponent Blur()
{
using (_logger.BeginLogScope($"Bluring {Metadata.Name}"))
using (var scope = _logger.BeginLogScope($"Bluring {Metadata.Name}"))
{
RelocateOnStaleReference(() => WrappedElement.BlurAsync().GetAwaiter().GetResult());
scope.Execute(async () =>
{
await RelocateOnStaleReference(async () => await WrappedElement.BlurAsync());
});
}

return component;
Expand All @@ -354,9 +390,12 @@ public virtual TComponent Blur(Action<TConditions> when)
/// <returns>The same instance of the component to continue interaction with it.</returns>
public virtual TComponent ContextClick()
{
using (_logger.BeginLogScope($"Context clicking on {Metadata.Name}"))
using (var scope = _logger.BeginLogScope($"Context clicking on {Metadata.Name}"))
{
RelocateOnStaleReference(() => WrappedElement.ClickAsync(new Microsoft.Playwright.LocatorClickOptions { Button = Microsoft.Playwright.MouseButton.Right }).GetAwaiter().GetResult());
scope.Execute(async () =>
{
await RelocateOnStaleReference(async () => await WrappedElement.ClickAsync(new Microsoft.Playwright.LocatorClickOptions { Button = Microsoft.Playwright.MouseButton.Right }));
});
}

return component;
Expand All @@ -378,12 +417,15 @@ public virtual TComponent ContextClick(Action<TConditions> when)
/// <returns>The same instance of the component to continue interaction with it.</returns>
public virtual TComponent DoubleClick()
{
using (_logger.BeginLogScope($"Double clicking on {Metadata.Name}"))
using (var scope = _logger.BeginLogScope($"Double clicking on {Metadata.Name}"))
{
RelocateOnStaleReference(() => WrappedElement.DblClickAsync().GetAwaiter().GetResult());
}
scope.Execute(async () =>
{
await RelocateOnStaleReference(async () => await WrappedElement.DblClickAsync());
});

return component;
return component;
}
}

/// <inheritdoc cref="DoubleClick()"/>
Expand All @@ -403,9 +445,12 @@ public virtual TComponent DragAndDrop<TToComponent, TToConditions, TToCondition>
where TToConditions : BaseComponentConditions<TToConditions>
where TToCondition : BaseComponentConditions<TToComponent>
{
using (_logger.BeginLogScope($"Dragging {Metadata.Name} to {toComponent.Metadata.Name}"))
using (var scope = _logger.BeginLogScope($"Dragging {Metadata.Name} to {toComponent.Metadata.Name}"))
{
RelocateOnStaleReference(() => WrappedElement.DragToAsync(toComponent.WrappedElement).GetAwaiter().GetResult());
scope.Execute(async () =>

Check warning on line 450 in src/Yapoml.Playwright/Components/BaseComponent.Actions.cs

View workflow job for this annotation

GitHub Actions / build

This async method lacks 'await' operators and will run synchronously. Consider using the 'await' operator to await non-blocking API calls, or 'await Task.Run(...)' to do CPU-bound work on a background thread.

Check warning on line 450 in src/Yapoml.Playwright/Components/BaseComponent.Actions.cs

View workflow job for this annotation

GitHub Actions / build

This async method lacks 'await' operators and will run synchronously. Consider using the 'await' operator to await non-blocking API calls, or 'await Task.Run(...)' to do CPU-bound work on a background thread.

Check warning on line 450 in src/Yapoml.Playwright/Components/BaseComponent.Actions.cs

View workflow job for this annotation

GitHub Actions / build

This async method lacks 'await' operators and will run synchronously. Consider using the 'await' operator to await non-blocking API calls, or 'await Task.Run(...)' to do CPU-bound work on a background thread.

Check warning on line 450 in src/Yapoml.Playwright/Components/BaseComponent.Actions.cs

View workflow job for this annotation

GitHub Actions / build

This async method lacks 'await' operators and will run synchronously. Consider using the 'await' operator to await non-blocking API calls, or 'await Task.Run(...)' to do CPU-bound work on a background thread.

Check warning on line 450 in src/Yapoml.Playwright/Components/BaseComponent.Actions.cs

View workflow job for this annotation

GitHub Actions / build

This async method lacks 'await' operators and will run synchronously. Consider using the 'await' operator to await non-blocking API calls, or 'await Task.Run(...)' to do CPU-bound work on a background thread.

Check warning on line 450 in src/Yapoml.Playwright/Components/BaseComponent.Actions.cs

View workflow job for this annotation

GitHub Actions / build

This async method lacks 'await' operators and will run synchronously. Consider using the 'await' operator to await non-blocking API calls, or 'await Task.Run(...)' to do CPU-bound work on a background thread.

Check warning on line 450 in src/Yapoml.Playwright/Components/BaseComponent.Actions.cs

View workflow job for this annotation

GitHub Actions / build

This async method lacks 'await' operators and will run synchronously. Consider using the 'await' operator to await non-blocking API calls, or 'await Task.Run(...)' to do CPU-bound work on a background thread.
{
RelocateOnStaleReference(async () => await WrappedElement.DragToAsync(toComponent.WrappedElement));

Check warning on line 452 in src/Yapoml.Playwright/Components/BaseComponent.Actions.cs

View workflow job for this annotation

GitHub Actions / build

Because this call is not awaited, execution of the current method continues before the call is completed. Consider applying the 'await' operator to the result of the call.

Check warning on line 452 in src/Yapoml.Playwright/Components/BaseComponent.Actions.cs

View workflow job for this annotation

GitHub Actions / build

Because this call is not awaited, execution of the current method continues before the call is completed. Consider applying the 'await' operator to the result of the call.

Check warning on line 452 in src/Yapoml.Playwright/Components/BaseComponent.Actions.cs

View workflow job for this annotation

GitHub Actions / build

Because this call is not awaited, execution of the current method continues before the call is completed. Consider applying the 'await' operator to the result of the call.

Check warning on line 452 in src/Yapoml.Playwright/Components/BaseComponent.Actions.cs

View workflow job for this annotation

GitHub Actions / build

Because this call is not awaited, execution of the current method continues before the call is completed. Consider applying the 'await' operator to the result of the call.

Check warning on line 452 in src/Yapoml.Playwright/Components/BaseComponent.Actions.cs

View workflow job for this annotation

GitHub Actions / build

Because this call is not awaited, execution of the current method continues before the call is completed. Consider applying the 'await' operator to the result of the call.

Check warning on line 452 in src/Yapoml.Playwright/Components/BaseComponent.Actions.cs

View workflow job for this annotation

GitHub Actions / build

Because this call is not awaited, execution of the current method continues before the call is completed. Consider applying the 'await' operator to the result of the call.

Check warning on line 452 in src/Yapoml.Playwright/Components/BaseComponent.Actions.cs

View workflow job for this annotation

GitHub Actions / build

Because this call is not awaited, execution of the current method continues before the call is completed. Consider applying the 'await' operator to the result of the call.
});
}

return component;
Expand Down
1 change: 1 addition & 0 deletions src/Yapoml.Playwright/Components/BaseComponent.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
using Yapoml.Playwright.Components.Metadata;
using Yapoml.Playwright.Options;
using Microsoft.Playwright;
using System.Threading.Tasks;

namespace Yapoml.Playwright.Components
{
Expand Down
Loading

0 comments on commit 8c69aff

Please sign in to comment.