Skip to content

Commit

Permalink
fix(locator): add missing tests, fix related bugs (#1762)
Browse files Browse the repository at this point in the history
  • Loading branch information
pavelfeldman authored Sep 27, 2021
1 parent 8728ace commit 479615e
Show file tree
Hide file tree
Showing 3 changed files with 125 additions and 3 deletions.
85 changes: 85 additions & 0 deletions src/Playwright.Tests/Locator/LocatorQueryTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
/*
* MIT License
*
* Copyright (c) Microsoft Corporation.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/

using System.Threading.Tasks;
using NUnit.Framework;

namespace Microsoft.Playwright.Tests.Locator
{
public class LocatorQueryTests : PageTestEx
{
[PlaywrightTest("locator-query.spec.ts", "should respect first() and last()")]
public async Task ShouldRespectFirstAndLast()
{
await Page.SetContentAsync(@"
<section>
<div><p>A</p></div>
<div><p>A</p><p>A</p></div>
<div><p>A</p><p>A</p><p>A</p></div>
</section>");
Assert.AreEqual(6, await Page.Locator("div >> p").CountAsync());
Assert.AreEqual(6, await Page.Locator("div").Locator("p").CountAsync());
Assert.AreEqual(1, await Page.Locator("div").First.Locator("p").CountAsync());
Assert.AreEqual(3, await Page.Locator("div").Last.Locator("p").CountAsync());
}

[PlaywrightTest("locator-query.spec.ts", "should respect nth()")]
public async Task ShouldRespectNth()
{
await Page.SetContentAsync(@"
<section>
<div><p>A</p></div>
<div><p>A</p><p>A</p></div>
<div><p>A</p><p>A</p><p>A</p></div>
</section>");
Assert.AreEqual(1, await Page.Locator("div >> p").Nth(0).CountAsync());
Assert.AreEqual(2, await Page.Locator("div").Nth(1).Locator("p").CountAsync());
Assert.AreEqual(3, await Page.Locator("div").Nth(2).Locator("p").CountAsync());
}

[PlaywrightTest("locator-query.spec.ts", "should throw on capture w/ nth()")]
public async Task ShouldThrowOnCaptureWithNth()
{
await Page.SetContentAsync("<section><div><p>A</p></div></section>");
var exception = await PlaywrightAssert.ThrowsAsync<PlaywrightException>(() => Page.Locator("*css=div >> p").Nth(1).ClickAsync());
StringAssert.Contains("Can't query n-th element", exception.Message);
}

[PlaywrightTest("locator-query.spec.ts", "should throw on due to strictness")]
public async Task ShouldThrowDueToStrictness()
{
await Page.SetContentAsync("<div>A</div><div>B</div>");
var exception = await PlaywrightAssert.ThrowsAsync<PlaywrightException>(() => Page.Locator("div").IsVisibleAsync());
StringAssert.Contains("strict mode violation", exception.Message);
}

[PlaywrightTest("locator-query.spec.ts", "should throw on due to strictness 2")]
public async Task ShouldThrowDueToStrictness2()
{
await Page.SetContentAsync("<select><option>One</option><option>Two</option></select>");
var exception = await PlaywrightAssert.ThrowsAsync<PlaywrightException>(() => Page.Locator("option").EvaluateAsync("() => {}"));
StringAssert.Contains("strict mode violation", exception.Message);
}
}
}
34 changes: 34 additions & 0 deletions src/Playwright/API/Supplements/ILocator.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/*
* MIT License
*
* Copyright (c) Microsoft Corporation.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/

using System.Text.Json;
using System.Threading.Tasks;

namespace Microsoft.Playwright
{
public partial interface ILocator
{
Task<JsonElement?> EvaluateAsync(string expression, object arg = null, LocatorEvaluateOptions options = null);
}
}
9 changes: 6 additions & 3 deletions src/Playwright/Core/Locator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,9 @@ public Locator(Frame parent, string selector)
_selector = selector;
}

public ILocator First => new Locator(_frame, $"{_selector} >> _nth=first");
public ILocator First => new Locator(_frame, $"{_selector} >> nth=0");

public ILocator Last => new Locator(_frame, $"{_selector} >> _nth=last");
public ILocator Last => new Locator(_frame, $"{_selector} >> nth=-1");

public async Task<IReadOnlyList<string>> AllInnerTextsAsync()
{
Expand Down Expand Up @@ -121,6 +121,9 @@ public Task<IReadOnlyList<IElementHandle>> ElementHandlesAsync()
public Task<T> EvaluateAllAsync<T>(string expression, object arg = null)
=> _frame.EvalOnSelectorAllAsync<T>(_selector, expression, arg);

public Task<JsonElement?> EvaluateAsync(string expression, object arg = null, LocatorEvaluateOptions options = null)
=> EvaluateAsync<JsonElement?>(expression, arg, options);

public Task<T> EvaluateAsync<T>(string expression, object arg = null, LocatorEvaluateOptions options = null)
=> _frame.EvalOnSelectorAsync<T>(_selector, expression, arg, ConvertOptions<FrameEvalOnSelectorOptions>(options));

Expand Down Expand Up @@ -167,7 +170,7 @@ public Task<bool> IsVisibleAsync(LocatorIsVisibleOptions options = null)
=> _frame.IsVisibleAsync(_selector, ConvertOptions<FrameIsVisibleOptions>(options));

public ILocator Nth(int index)
=> new Locator(_frame, $"{_selector} >> _nth=${index}");
=> new Locator(_frame, $"{_selector} >> nth={index}");

public Task PressAsync(string key, LocatorPressOptions options = null)
=> _frame.PressAsync(_selector, key, ConvertOptions<FramePressOptions>(options));
Expand Down

0 comments on commit 479615e

Please sign in to comment.