Skip to content

Commit

Permalink
Revert "Fix Race Condition, Login Issues + Upgrade Playwright ver" (#259
Browse files Browse the repository at this point in the history
)
  • Loading branch information
landonmsft authored May 15, 2023
1 parent 14d45d8 commit 8b52985
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 146 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -251,14 +251,14 @@ public async Task SetupNetworkRequestMockAsyncTest()
MockSingleTestInstanceState.Setup(x => x.GetTestSuiteDefinition()).Returns(testSuiteDefinition);
MockFileSystem.Setup(x => x.IsValidFilePath(It.IsAny<string>())).Returns(true);
MockBrowserContext.Setup(x => x.NewPageAsync()).Returns(Task.FromResult(MockPage.Object));
MockPage.Setup(x => x.RouteAsync(mock.RequestURL, It.IsAny<Func<IRoute, Task>>(), It.IsAny<PageRouteOptions>())).Returns(Task.FromResult<IResponse?>(MockResponse.Object));
MockPage.Setup(x => x.RouteAsync(mock.RequestURL, It.IsAny<Action<IRoute>>(), It.IsAny<PageRouteOptions>())).Returns(Task.FromResult<IResponse?>(MockResponse.Object));

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

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

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

[Fact]
public async Task HandleUserPasswordScreen()
{
string testSelector = "input:has-text('Password')";
string testTextEntry = "*****";
string desiredUrl = "https://make.powerapps.com";

MockSingleTestInstanceState.Setup(x => x.GetLogger()).Returns(MockLogger.Object);
LoggingTestHelper.SetupMock(MockLogger);

var mockLocator = new Mock<ILocator>(MockBehavior.Strict);
MockPage.Setup(x => x.Locator(It.IsAny<string>(), null)).Returns(mockLocator.Object);
mockLocator.Setup(x => x.WaitForAsync(null)).Returns(Task.CompletedTask);

MockPage.Setup(x => x.FillAsync(testSelector, testTextEntry, null)).Returns(Task.CompletedTask);
MockPage.Setup(x => x.ClickAsync("input[type=\"submit\"]", null)).Returns(Task.CompletedTask);
// Assume ask already logged in
MockPage.Setup(x => x.WaitForSelectorAsync("[id=\"KmsiCheckboxField\"]", It.IsAny<PageWaitForSelectorOptions>())).Returns(Task.FromResult(MockElementHandle.Object));
// Simulate Click to stay signed in
MockPage.Setup(x => x.ClickAsync("[id=\"idBtn_Back\"]", null)).Returns(Task.CompletedTask);
// Wait until login is complete and redirect to desired page
MockPage.Setup(x => x.WaitForURLAsync(desiredUrl, null)).Returns(Task.CompletedTask);

var playwrightTestInfraFunctions = new PlaywrightTestInfraFunctions(MockTestState.Object, MockSingleTestInstanceState.Object,
MockFileSystem.Object, browserContext: MockBrowserContext.Object, page: MockPage.Object);

await playwrightTestInfraFunctions.HandleUserPasswordScreen(testSelector, testTextEntry, desiredUrl);

MockPage.Verify(x => x.Locator(It.Is<string>(v => v.Equals(testSelector)), null));
MockPage.Verify(x => x.WaitForSelectorAsync("[id=\"KmsiCheckboxField\"]", It.Is<PageWaitForSelectorOptions>(v => v.Timeout >= 8000)));
}

[Fact]
public async Task HandleUserPasswordScreenErrorEntry()
{
string testSelector = "input:has-text('Password')";
string testTextEntry = "*****";
string desiredUrl = "https://make.powerapps.com";

MockSingleTestInstanceState.Setup(x => x.GetLogger()).Returns(MockLogger.Object);
LoggingTestHelper.SetupMock(MockLogger);

var mockLocator = new Mock<ILocator>(MockBehavior.Strict);
MockPage.Setup(x => x.Locator(It.IsAny<string>(), null)).Returns(mockLocator.Object);
mockLocator.Setup(x => x.WaitForAsync(null)).Returns(Task.CompletedTask);

MockPage.Setup(x => x.FillAsync(testSelector, testTextEntry, null)).Returns(Task.CompletedTask);
MockPage.Setup(x => x.ClickAsync("input[type=\"submit\"]", null)).Returns(Task.CompletedTask);
// Not ask to sign in as selector not found
MockPage.Setup(x => x.WaitForSelectorAsync("[id=\"KmsiCheckboxField\"]", It.IsAny<PageWaitForSelectorOptions>())).Throws(new TimeoutException());
// Simulate error response for password error
MockPage.Setup(x => x.WaitForSelectorAsync("[id=\"passwordError\"]", It.IsAny<PageWaitForSelectorOptions>())).Returns(Task.FromResult(MockElementHandle.Object));
// Throw exception as not make it to desired url
MockPage.Setup(x => x.WaitForURLAsync(desiredUrl, null)).Throws(new TimeoutException());

var playwrightTestInfraFunctions = new PlaywrightTestInfraFunctions(MockTestState.Object, MockSingleTestInstanceState.Object,
MockFileSystem.Object, browserContext: MockBrowserContext.Object, page: MockPage.Object);

await Assert.ThrowsAsync<InvalidOperationException>(async () => await playwrightTestInfraFunctions.HandleUserPasswordScreen(testSelector, testTextEntry, desiredUrl));

MockPage.Verify(x => x.Locator(It.Is<string>(v => v.Equals(testSelector)), null));
MockPage.Verify(x => x.WaitForSelectorAsync("[id=\"passwordError\"]", It.Is<PageWaitForSelectorOptions>(v => v.Timeout >= 2000)));
}

[Fact]
public async Task HandleUserPasswordScreenUnknownError()
{
string testSelector = "input:has-text('Password')";
string testTextEntry = "*****";
string desiredUrl = "https://make.powerapps.com";

MockSingleTestInstanceState.Setup(x => x.GetLogger()).Returns(MockLogger.Object);
LoggingTestHelper.SetupMock(MockLogger);

var mockLocator = new Mock<ILocator>(MockBehavior.Strict);
MockPage.Setup(x => x.Locator(It.IsAny<string>(), null)).Returns(mockLocator.Object);
mockLocator.Setup(x => x.WaitForAsync(null)).Returns(Task.CompletedTask);

MockPage.Setup(x => x.FillAsync(testSelector, testTextEntry, null)).Returns(Task.CompletedTask);
MockPage.Setup(x => x.ClickAsync("input[type=\"submit\"]", null)).Returns(Task.CompletedTask);
// Not ask to sign in as selector not found
MockPage.Setup(x => x.WaitForSelectorAsync("[id=\"KmsiCheckboxField\"]", null)).Throws(new TimeoutException());
// Also not able to find password error, must be some other error
MockPage.Setup(x => x.WaitForSelectorAsync("[id=\"passwordError\"]", It.IsAny<PageWaitForSelectorOptions>())).Throws(new TimeoutException());
// Throw exception as not make it to desired url
MockPage.Setup(x => x.WaitForURLAsync(desiredUrl, null)).Throws(new TimeoutException());

var playwrightTestInfraFunctions = new PlaywrightTestInfraFunctions(MockTestState.Object, MockSingleTestInstanceState.Object,
MockFileSystem.Object, browserContext: MockBrowserContext.Object, page: MockPage.Object);

await Assert.ThrowsAsync<TimeoutException>(async () => await playwrightTestInfraFunctions.HandleUserPasswordScreen(testSelector, testTextEntry, desiredUrl));

MockPage.Verify(x => x.Locator(It.Is<string>(v => v.Equals(testSelector)), null));
}

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="6.0.0" />
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="6.0.0" />
<PackageReference Include="Microsoft.Playwright" Version="1.33.0" />
<PackageReference Include="Microsoft.Playwright" Version="1.22.0" />
<PackageReference Include="Microsoft.PowerFx.Interpreter" Version="0.2.3-preview" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.2" />
<PackageReference Include="YamlDotNet" Version="11.2.1" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -295,75 +295,88 @@ public async Task HandleUserEmailScreen(string selector, string value)
await Page.Keyboard.PressAsync("Tab", new KeyboardPressOptions { Delay = 20 });
}

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

// Setting options fot the RunAndWaitForNavigationAsync function
PageRunAndWaitForNavigationOptions options = new PageRunAndWaitForNavigationOptions();

// URL that should be redirected to
options.UrlString = desiredUrl;

ValidatePage();

try
{
// Find the password box
await Page.Locator(selector).WaitForAsync();

// Fill in the password
await Page.FillAsync(selector, value);

// Submit password form
await this.ClickAsync("input[type=\"submit\"]");

PageWaitForSelectorOptions selectorOptions = new PageWaitForSelectorOptions();
selectorOptions.Timeout = 8000;

// For instances where there is a 'Stay signed in?' dialogue box
try
// Only continue if redirected to the correct page
await Page.RunAndWaitForNavigationAsync(async () =>
{
logger.LogDebug("Checking if asked to stay signed in.");
// Find the password box
await Page.Locator(selector).WaitForAsync();
// Check if we received a 'Stay signed in?' box?
await Page.WaitForSelectorAsync("[id=\"KmsiCheckboxField\"]", selectorOptions);
logger.LogDebug("Was asked to 'stay signed in'.");
// Fill in the password
await Page.FillAsync(selector, value);
// Click to stay signed in
await Page.ClickAsync("[id=\"idBtn_Back\"]");
}
// If there is no 'Stay signed in?' box, an exception will throw; just catch and continue
catch (Exception ssiException)
{
logger.LogDebug("Exception encountered: " + ssiException.ToString());
// Submit password form
await this.ClickAsync("input[type=\"submit\"]");
// Keep record if passwordError was encountered
bool hasPasswordError = false;
PageWaitForSelectorOptions selectorOptions = new PageWaitForSelectorOptions();
selectorOptions.Timeout = 8000;
// For instances where there is a 'Stay signed in?' dialogue box
try
{
selectorOptions.Timeout = 2000;
logger.LogDebug("Checking if asked to stay signed in.");
// Check if we received a password error
await Page.WaitForSelectorAsync("[id=\"passwordError\"]", selectorOptions);
hasPasswordError = true;
}
catch (Exception peException)
{
logger.LogDebug("Exception encountered: " + peException.ToString());
}
// Check if we received a 'Stay signed in?' box?
await Page.WaitForSelectorAsync("[id=\"KmsiCheckboxField\"]", selectorOptions);
logger.LogDebug("Was asked to 'stay signed in'.");
// If encountered password error, exit program
if (hasPasswordError)
{
logger.LogError("Incorrect password entered. Make sure you are using the correct credentials.");
throw new InvalidOperationException();
// Click to stay signed in
await Page.ClickAsync("[id=\"idBtn_Back\"]");
}
// If not, continue
else
// If there is no 'Stay signed in?' box, an exception will throw; just catch and continue
catch (Exception ssiException)
{
logger.LogDebug("Did not encounter an invalid password error.");
logger.LogDebug("Exception encountered: " + ssiException.ToString());
// Keep record if passwordError was encountered
bool hasPasswordError = false;
try
{
selectorOptions.Timeout = 2000;
// Check if we received a password error
await Page.WaitForSelectorAsync("[id=\"passwordError\"]", selectorOptions);
hasPasswordError = true;
}
catch (Exception peException)
{
logger.LogDebug("Exception encountered: " + peException.ToString());
}
// If encountered password error, exit program
if (hasPasswordError)
{
logger.LogError("Incorrect password entered. Make sure you are using the correct credentials.");
throw new InvalidOperationException();
}
// If not, continue
else
{
logger.LogDebug("Did not encounter an invalid password error.");
}
logger.LogDebug("Was not asked to 'stay signed in'.");
}
logger.LogDebug("Was not asked to 'stay signed in'.");
}

await Page.WaitForURLAsync(desiredUrl);
await Page.WaitForLoadStateAsync(LoadState.NetworkIdle);
}, options);
}
catch (TimeoutException)
{
Expand Down

0 comments on commit 8b52985

Please sign in to comment.