Skip to content

Commit 8b52985

Browse files
authored
Revert "Fix Race Condition, Login Issues + Upgrade Playwright ver" (#259)
1 parent 14d45d8 commit 8b52985

File tree

3 files changed

+64
-146
lines changed

3 files changed

+64
-146
lines changed

src/Microsoft.PowerApps.TestEngine.Tests/TestInfra/PlaywrightTestInfraFunctionTests.cs

Lines changed: 2 additions & 97 deletions
Original file line numberDiff line numberDiff line change
@@ -251,14 +251,14 @@ public async Task SetupNetworkRequestMockAsyncTest()
251251
MockSingleTestInstanceState.Setup(x => x.GetTestSuiteDefinition()).Returns(testSuiteDefinition);
252252
MockFileSystem.Setup(x => x.IsValidFilePath(It.IsAny<string>())).Returns(true);
253253
MockBrowserContext.Setup(x => x.NewPageAsync()).Returns(Task.FromResult(MockPage.Object));
254-
MockPage.Setup(x => x.RouteAsync(mock.RequestURL, It.IsAny<Func<IRoute, Task>>(), It.IsAny<PageRouteOptions>())).Returns(Task.FromResult<IResponse?>(MockResponse.Object));
254+
MockPage.Setup(x => x.RouteAsync(mock.RequestURL, It.IsAny<Action<IRoute>>(), It.IsAny<PageRouteOptions>())).Returns(Task.FromResult<IResponse?>(MockResponse.Object));
255255

256256
var playwrightTestInfraFunctions = new PlaywrightTestInfraFunctions(MockTestState.Object, MockSingleTestInstanceState.Object,
257257
MockFileSystem.Object, browserContext: MockBrowserContext.Object);
258258
await playwrightTestInfraFunctions.SetupNetworkRequestMockAsync();
259259

260260
MockBrowserContext.Verify(x => x.NewPageAsync(), Times.Once);
261-
MockPage.Verify(x => x.RouteAsync(mock.RequestURL, It.IsAny<Func<IRoute, Task>>(), It.IsAny<PageRouteOptions>()), Times.Once);
261+
MockPage.Verify(x => x.RouteAsync(mock.RequestURL, It.IsAny<Action<IRoute>>(), It.IsAny<PageRouteOptions>()), Times.Once);
262262
MockFileSystem.Verify(x => x.IsValidFilePath(mock.ResponseDataFile), Times.Once());
263263
}
264264

@@ -618,100 +618,5 @@ public async Task RouteNetworkRequestTest()
618618
MockRoute.Verify(x => x.ContinueAsync(It.IsAny<RouteContinueOptions>()), Times.Once);
619619
}
620620

621-
[Fact]
622-
public async Task HandleUserPasswordScreen()
623-
{
624-
string testSelector = "input:has-text('Password')";
625-
string testTextEntry = "*****";
626-
string desiredUrl = "https://make.powerapps.com";
627-
628-
MockSingleTestInstanceState.Setup(x => x.GetLogger()).Returns(MockLogger.Object);
629-
LoggingTestHelper.SetupMock(MockLogger);
630-
631-
var mockLocator = new Mock<ILocator>(MockBehavior.Strict);
632-
MockPage.Setup(x => x.Locator(It.IsAny<string>(), null)).Returns(mockLocator.Object);
633-
mockLocator.Setup(x => x.WaitForAsync(null)).Returns(Task.CompletedTask);
634-
635-
MockPage.Setup(x => x.FillAsync(testSelector, testTextEntry, null)).Returns(Task.CompletedTask);
636-
MockPage.Setup(x => x.ClickAsync("input[type=\"submit\"]", null)).Returns(Task.CompletedTask);
637-
// Assume ask already logged in
638-
MockPage.Setup(x => x.WaitForSelectorAsync("[id=\"KmsiCheckboxField\"]", It.IsAny<PageWaitForSelectorOptions>())).Returns(Task.FromResult(MockElementHandle.Object));
639-
// Simulate Click to stay signed in
640-
MockPage.Setup(x => x.ClickAsync("[id=\"idBtn_Back\"]", null)).Returns(Task.CompletedTask);
641-
// Wait until login is complete and redirect to desired page
642-
MockPage.Setup(x => x.WaitForURLAsync(desiredUrl, null)).Returns(Task.CompletedTask);
643-
644-
var playwrightTestInfraFunctions = new PlaywrightTestInfraFunctions(MockTestState.Object, MockSingleTestInstanceState.Object,
645-
MockFileSystem.Object, browserContext: MockBrowserContext.Object, page: MockPage.Object);
646-
647-
await playwrightTestInfraFunctions.HandleUserPasswordScreen(testSelector, testTextEntry, desiredUrl);
648-
649-
MockPage.Verify(x => x.Locator(It.Is<string>(v => v.Equals(testSelector)), null));
650-
MockPage.Verify(x => x.WaitForSelectorAsync("[id=\"KmsiCheckboxField\"]", It.Is<PageWaitForSelectorOptions>(v => v.Timeout >= 8000)));
651-
}
652-
653-
[Fact]
654-
public async Task HandleUserPasswordScreenErrorEntry()
655-
{
656-
string testSelector = "input:has-text('Password')";
657-
string testTextEntry = "*****";
658-
string desiredUrl = "https://make.powerapps.com";
659-
660-
MockSingleTestInstanceState.Setup(x => x.GetLogger()).Returns(MockLogger.Object);
661-
LoggingTestHelper.SetupMock(MockLogger);
662-
663-
var mockLocator = new Mock<ILocator>(MockBehavior.Strict);
664-
MockPage.Setup(x => x.Locator(It.IsAny<string>(), null)).Returns(mockLocator.Object);
665-
mockLocator.Setup(x => x.WaitForAsync(null)).Returns(Task.CompletedTask);
666-
667-
MockPage.Setup(x => x.FillAsync(testSelector, testTextEntry, null)).Returns(Task.CompletedTask);
668-
MockPage.Setup(x => x.ClickAsync("input[type=\"submit\"]", null)).Returns(Task.CompletedTask);
669-
// Not ask to sign in as selector not found
670-
MockPage.Setup(x => x.WaitForSelectorAsync("[id=\"KmsiCheckboxField\"]", It.IsAny<PageWaitForSelectorOptions>())).Throws(new TimeoutException());
671-
// Simulate error response for password error
672-
MockPage.Setup(x => x.WaitForSelectorAsync("[id=\"passwordError\"]", It.IsAny<PageWaitForSelectorOptions>())).Returns(Task.FromResult(MockElementHandle.Object));
673-
// Throw exception as not make it to desired url
674-
MockPage.Setup(x => x.WaitForURLAsync(desiredUrl, null)).Throws(new TimeoutException());
675-
676-
var playwrightTestInfraFunctions = new PlaywrightTestInfraFunctions(MockTestState.Object, MockSingleTestInstanceState.Object,
677-
MockFileSystem.Object, browserContext: MockBrowserContext.Object, page: MockPage.Object);
678-
679-
await Assert.ThrowsAsync<InvalidOperationException>(async () => await playwrightTestInfraFunctions.HandleUserPasswordScreen(testSelector, testTextEntry, desiredUrl));
680-
681-
MockPage.Verify(x => x.Locator(It.Is<string>(v => v.Equals(testSelector)), null));
682-
MockPage.Verify(x => x.WaitForSelectorAsync("[id=\"passwordError\"]", It.Is<PageWaitForSelectorOptions>(v => v.Timeout >= 2000)));
683-
}
684-
685-
[Fact]
686-
public async Task HandleUserPasswordScreenUnknownError()
687-
{
688-
string testSelector = "input:has-text('Password')";
689-
string testTextEntry = "*****";
690-
string desiredUrl = "https://make.powerapps.com";
691-
692-
MockSingleTestInstanceState.Setup(x => x.GetLogger()).Returns(MockLogger.Object);
693-
LoggingTestHelper.SetupMock(MockLogger);
694-
695-
var mockLocator = new Mock<ILocator>(MockBehavior.Strict);
696-
MockPage.Setup(x => x.Locator(It.IsAny<string>(), null)).Returns(mockLocator.Object);
697-
mockLocator.Setup(x => x.WaitForAsync(null)).Returns(Task.CompletedTask);
698-
699-
MockPage.Setup(x => x.FillAsync(testSelector, testTextEntry, null)).Returns(Task.CompletedTask);
700-
MockPage.Setup(x => x.ClickAsync("input[type=\"submit\"]", null)).Returns(Task.CompletedTask);
701-
// Not ask to sign in as selector not found
702-
MockPage.Setup(x => x.WaitForSelectorAsync("[id=\"KmsiCheckboxField\"]", null)).Throws(new TimeoutException());
703-
// Also not able to find password error, must be some other error
704-
MockPage.Setup(x => x.WaitForSelectorAsync("[id=\"passwordError\"]", It.IsAny<PageWaitForSelectorOptions>())).Throws(new TimeoutException());
705-
// Throw exception as not make it to desired url
706-
MockPage.Setup(x => x.WaitForURLAsync(desiredUrl, null)).Throws(new TimeoutException());
707-
708-
var playwrightTestInfraFunctions = new PlaywrightTestInfraFunctions(MockTestState.Object, MockSingleTestInstanceState.Object,
709-
MockFileSystem.Object, browserContext: MockBrowserContext.Object, page: MockPage.Object);
710-
711-
await Assert.ThrowsAsync<TimeoutException>(async () => await playwrightTestInfraFunctions.HandleUserPasswordScreen(testSelector, testTextEntry, desiredUrl));
712-
713-
MockPage.Verify(x => x.Locator(It.Is<string>(v => v.Equals(testSelector)), null));
714-
}
715-
716621
}
717622
}

src/Microsoft.PowerApps.TestEngine/Microsoft.PowerApps.TestEngine.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929
<ItemGroup>
3030
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="6.0.0" />
3131
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="6.0.0" />
32-
<PackageReference Include="Microsoft.Playwright" Version="1.33.0" />
32+
<PackageReference Include="Microsoft.Playwright" Version="1.22.0" />
3333
<PackageReference Include="Microsoft.PowerFx.Interpreter" Version="0.2.3-preview" />
3434
<PackageReference Include="Newtonsoft.Json" Version="13.0.2" />
3535
<PackageReference Include="YamlDotNet" Version="11.2.1" />

src/Microsoft.PowerApps.TestEngine/TestInfra/PlaywrightTestInfraFunctions.cs

Lines changed: 61 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -295,75 +295,88 @@ public async Task HandleUserEmailScreen(string selector, string value)
295295
await Page.Keyboard.PressAsync("Tab", new KeyboardPressOptions { Delay = 20 });
296296
}
297297

298+
// Justification: Limited ability to run unit tests for
299+
// Playwright actions on the sign-in page
300+
[ExcludeFromCodeCoverage]
298301
public async Task HandleUserPasswordScreen(string selector, string value, string desiredUrl)
299302
{
300303
var logger = _singleTestInstanceState.GetLogger();
301304

305+
// Setting options fot the RunAndWaitForNavigationAsync function
306+
PageRunAndWaitForNavigationOptions options = new PageRunAndWaitForNavigationOptions();
307+
308+
// URL that should be redirected to
309+
options.UrlString = desiredUrl;
310+
302311
ValidatePage();
303312

304313
try
305314
{
306-
// Find the password box
307-
await Page.Locator(selector).WaitForAsync();
308-
309-
// Fill in the password
310-
await Page.FillAsync(selector, value);
311-
312-
// Submit password form
313-
await this.ClickAsync("input[type=\"submit\"]");
314-
315-
PageWaitForSelectorOptions selectorOptions = new PageWaitForSelectorOptions();
316-
selectorOptions.Timeout = 8000;
317-
318-
// For instances where there is a 'Stay signed in?' dialogue box
319-
try
315+
// Only continue if redirected to the correct page
316+
await Page.RunAndWaitForNavigationAsync(async () =>
320317
{
321-
logger.LogDebug("Checking if asked to stay signed in.");
318+
// Find the password box
319+
await Page.Locator(selector).WaitForAsync();
322320

323-
// Check if we received a 'Stay signed in?' box?
324-
await Page.WaitForSelectorAsync("[id=\"KmsiCheckboxField\"]", selectorOptions);
325-
logger.LogDebug("Was asked to 'stay signed in'.");
321+
// Fill in the password
322+
await Page.FillAsync(selector, value);
326323

327-
// Click to stay signed in
328-
await Page.ClickAsync("[id=\"idBtn_Back\"]");
329-
}
330-
// If there is no 'Stay signed in?' box, an exception will throw; just catch and continue
331-
catch (Exception ssiException)
332-
{
333-
logger.LogDebug("Exception encountered: " + ssiException.ToString());
324+
// Submit password form
325+
await this.ClickAsync("input[type=\"submit\"]");
334326

335-
// Keep record if passwordError was encountered
336-
bool hasPasswordError = false;
327+
PageWaitForSelectorOptions selectorOptions = new PageWaitForSelectorOptions();
328+
selectorOptions.Timeout = 8000;
337329

330+
// For instances where there is a 'Stay signed in?' dialogue box
338331
try
339332
{
340-
selectorOptions.Timeout = 2000;
333+
logger.LogDebug("Checking if asked to stay signed in.");
341334

342-
// Check if we received a password error
343-
await Page.WaitForSelectorAsync("[id=\"passwordError\"]", selectorOptions);
344-
hasPasswordError = true;
345-
}
346-
catch (Exception peException)
347-
{
348-
logger.LogDebug("Exception encountered: " + peException.ToString());
349-
}
335+
// Check if we received a 'Stay signed in?' box?
336+
await Page.WaitForSelectorAsync("[id=\"KmsiCheckboxField\"]", selectorOptions);
337+
logger.LogDebug("Was asked to 'stay signed in'.");
350338

351-
// If encountered password error, exit program
352-
if (hasPasswordError)
353-
{
354-
logger.LogError("Incorrect password entered. Make sure you are using the correct credentials.");
355-
throw new InvalidOperationException();
339+
// Click to stay signed in
340+
await Page.ClickAsync("[id=\"idBtn_Back\"]");
356341
}
357-
// If not, continue
358-
else
342+
// If there is no 'Stay signed in?' box, an exception will throw; just catch and continue
343+
catch (Exception ssiException)
359344
{
360-
logger.LogDebug("Did not encounter an invalid password error.");
345+
logger.LogDebug("Exception encountered: " + ssiException.ToString());
346+
347+
// Keep record if passwordError was encountered
348+
bool hasPasswordError = false;
349+
350+
try
351+
{
352+
selectorOptions.Timeout = 2000;
353+
354+
// Check if we received a password error
355+
await Page.WaitForSelectorAsync("[id=\"passwordError\"]", selectorOptions);
356+
hasPasswordError = true;
357+
}
358+
catch (Exception peException)
359+
{
360+
logger.LogDebug("Exception encountered: " + peException.ToString());
361+
}
362+
363+
// If encountered password error, exit program
364+
if (hasPasswordError)
365+
{
366+
logger.LogError("Incorrect password entered. Make sure you are using the correct credentials.");
367+
throw new InvalidOperationException();
368+
}
369+
// If not, continue
370+
else
371+
{
372+
logger.LogDebug("Did not encounter an invalid password error.");
373+
}
374+
375+
logger.LogDebug("Was not asked to 'stay signed in'.");
361376
}
362377

363-
logger.LogDebug("Was not asked to 'stay signed in'.");
364-
}
365-
366-
await Page.WaitForURLAsync(desiredUrl);
378+
await Page.WaitForLoadStateAsync(LoadState.NetworkIdle);
379+
}, options);
367380
}
368381
catch (TimeoutException)
369382
{

0 commit comments

Comments
 (0)