Fix Selenium flakyness on Circle CI (#2904)

This commit is contained in:
Nicolas Dorier
2021-09-22 21:31:44 +09:00
committed by GitHub
parent ac34109da3
commit d0120f1427
6 changed files with 51 additions and 31 deletions

View File

@@ -124,8 +124,8 @@ namespace BTCPayServer.Tests
//redirect //redirect
//appidentifier //appidentifier
var appidentifier = "testapp"; var appidentifier = "testapp";
var callbackUrl = tester.PayTester.ServerUri + "postredirect-callback-test"; var callbackUrl = s.ServerUri + "postredirect-callback-test";
var authUrl = BTCPayServerClient.GenerateAuthorizeUri(tester.PayTester.ServerUri, var authUrl = BTCPayServerClient.GenerateAuthorizeUri(s.ServerUri,
new[] { Policies.CanModifyStoreSettings, Policies.CanModifyServerSettings }, applicationDetails: (appidentifier, new Uri(callbackUrl))).ToString(); new[] { Policies.CanModifyStoreSettings, Policies.CanModifyServerSettings }, applicationDetails: (appidentifier, new Uri(callbackUrl))).ToString();
s.Driver.Navigate().GoToUrl(authUrl); s.Driver.Navigate().GoToUrl(authUrl);
Assert.Contains(appidentifier, s.Driver.PageSource); Assert.Contains(appidentifier, s.Driver.PageSource);
@@ -143,7 +143,7 @@ namespace BTCPayServer.Tests
await TestApiAgainstAccessToken(accessToken, tester, user, await TestApiAgainstAccessToken(accessToken, tester, user,
(await apiKeyRepo.GetKey(accessToken)).GetBlob().Permissions); (await apiKeyRepo.GetKey(accessToken)).GetBlob().Permissions);
authUrl = BTCPayServerClient.GenerateAuthorizeUri(tester.PayTester.ServerUri, authUrl = BTCPayServerClient.GenerateAuthorizeUri(s.ServerUri,
new[] { Policies.CanModifyStoreSettings, Policies.CanModifyServerSettings }, false, true, applicationDetails: (null, new Uri(callbackUrl))).ToString(); new[] { Policies.CanModifyStoreSettings, Policies.CanModifyServerSettings }, false, true, applicationDetails: (null, new Uri(callbackUrl))).ToString();
s.Driver.Navigate().GoToUrl(authUrl); s.Driver.Navigate().GoToUrl(authUrl);
@@ -164,7 +164,7 @@ namespace BTCPayServer.Tests
(await apiKeyRepo.GetKey(accessToken)).GetBlob().Permissions); (await apiKeyRepo.GetKey(accessToken)).GetBlob().Permissions);
//let's test the app identifier system //let's test the app identifier system
authUrl = BTCPayServerClient.GenerateAuthorizeUri(tester.PayTester.ServerUri, authUrl = BTCPayServerClient.GenerateAuthorizeUri(s.ServerUri,
new[] { Policies.CanModifyStoreSettings, Policies.CanModifyServerSettings }, false, true, (appidentifier, new Uri(callbackUrl))).ToString(); new[] { Policies.CanModifyStoreSettings, Policies.CanModifyServerSettings }, false, true, (appidentifier, new Uri(callbackUrl))).ToString();
//if it's the same, go to the confirm page //if it's the same, go to the confirm page
@@ -173,7 +173,7 @@ namespace BTCPayServer.Tests
Assert.Equal(callbackUrl, s.Driver.Url); Assert.Equal(callbackUrl, s.Driver.Url);
//same app but different redirect = nono //same app but different redirect = nono
authUrl = BTCPayServerClient.GenerateAuthorizeUri(tester.PayTester.ServerUri, authUrl = BTCPayServerClient.GenerateAuthorizeUri(s.ServerUri,
new[] { Policies.CanModifyStoreSettings, Policies.CanModifyServerSettings }, false, true, (appidentifier, new Uri("https://international.local/callback"))).ToString(); new[] { Policies.CanModifyStoreSettings, Policies.CanModifyServerSettings }, false, true, (appidentifier, new Uri("https://international.local/callback"))).ToString();
s.Driver.Navigate().GoToUrl(authUrl); s.Driver.Navigate().GoToUrl(authUrl);

View File

@@ -163,7 +163,7 @@ namespace BTCPayServer.Tests
var invoiceId = s.CreateInvoice(store.storeId, 0.001m, "BTC", "a@x.com"); var invoiceId = s.CreateInvoice(store.storeId, 0.001m, "BTC", "a@x.com");
var invoice = await s.Server.PayTester.InvoiceRepository.GetInvoice(invoiceId); var invoice = await s.Server.PayTester.InvoiceRepository.GetInvoice(invoiceId);
s.Driver.Navigate() s.Driver.Navigate()
.GoToUrl(new Uri(s.Server.PayTester.ServerUri, $"tests/index.html?invoice={invoiceId}")); .GoToUrl(new Uri(s.ServerUri, $"tests/index.html?invoice={invoiceId}"));
TestUtils.Eventually(() => TestUtils.Eventually(() =>
{ {
Assert.True(s.Driver.FindElement(By.Name("btcpay")).Displayed); Assert.True(s.Driver.FindElement(By.Name("btcpay")).Displayed);
@@ -184,7 +184,7 @@ namespace BTCPayServer.Tests
closebutton.Click(); closebutton.Click();
s.Driver.AssertElementNotFound(By.Name("btcpay")); s.Driver.AssertElementNotFound(By.Name("btcpay"));
Assert.Equal(s.Driver.Url, Assert.Equal(s.Driver.Url,
new Uri(s.Server.PayTester.ServerUri, $"tests/index.html?invoice={invoiceId}").ToString()); new Uri(s.ServerUri, $"tests/index.html?invoice={invoiceId}").ToString());
} }
} }
} }

View File

@@ -53,11 +53,6 @@ namespace BTCPayServer.Tests
var chromeDriverPath = config["ChromeDriverDirectory"] ?? (Server.PayTester.InContainer ? "/usr/bin" : Directory.GetCurrentDirectory()); var chromeDriverPath = config["ChromeDriverDirectory"] ?? (Server.PayTester.InContainer ? "/usr/bin" : Directory.GetCurrentDirectory());
var options = new ChromeOptions(); var options = new ChromeOptions();
if (Server.PayTester.InContainer)
{
// this must be first option https://stackoverflow.com/questions/53073411/selenium-webdriverexceptionchrome-failed-to-start-crashed-as-google-chrome-is#comment102570662_53073789
options.AddArgument("no-sandbox");
}
if (!runInBrowser) if (!runInBrowser)
{ {
options.AddArguments("headless"); options.AddArguments("headless");
@@ -65,7 +60,16 @@ namespace BTCPayServer.Tests
options.AddArguments($"window-size={windowSize.Width}x{windowSize.Height}"); options.AddArguments($"window-size={windowSize.Width}x{windowSize.Height}");
options.AddArgument("shm-size=2g"); options.AddArgument("shm-size=2g");
options.AddArgument("start-maximized"); options.AddArgument("start-maximized");
if (Server.PayTester.InContainer)
{
Driver = new OpenQA.Selenium.Remote.RemoteWebDriver(new Uri("http://selenium:4444/wd/hub"), new RemoteSessionSettings(options));
var containerIp = File.ReadAllText("/etc/hosts").Split('\n', StringSplitOptions.RemoveEmptyEntries).Last()
.Split('\t', StringSplitOptions.RemoveEmptyEntries)[0].Trim();
Logs.Tester.LogInformation($"Selenium: Container's IP {containerIp}");
ServerUri = new Uri(Server.PayTester.ServerUri.AbsoluteUri.Replace($"http://{Server.PayTester.HostName}", $"http://{containerIp}", StringComparison.OrdinalIgnoreCase), UriKind.Absolute);
}
else
{
var cds = ChromeDriverService.CreateDefaultService(chromeDriverPath); var cds = ChromeDriverService.CreateDefaultService(chromeDriverPath);
cds.EnableVerboseLogging = true; cds.EnableVerboseLogging = true;
cds.Port = Utils.FreeTcpPort(); cds.Port = Utils.FreeTcpPort();
@@ -74,15 +78,21 @@ namespace BTCPayServer.Tests
Driver = new ChromeDriver(cds, options, Driver = new ChromeDriver(cds, options,
// A bit less than test timeout // A bit less than test timeout
TimeSpan.FromSeconds(50)); TimeSpan.FromSeconds(50));
ServerUri = Server.PayTester.ServerUri;
}
Driver.Manage().Window.Maximize(); Driver.Manage().Window.Maximize();
Logs.Tester.LogInformation($"Selenium: Using {Driver.GetType()}"); Logs.Tester.LogInformation($"Selenium: Using {Driver.GetType()}");
Logs.Tester.LogInformation($"Selenium: Browsing to {Server.PayTester.ServerUri}"); Logs.Tester.LogInformation($"Selenium: Browsing to {ServerUri}");
Logs.Tester.LogInformation($"Selenium: Resolution {Driver.Manage().Window.Size}"); Logs.Tester.LogInformation($"Selenium: Resolution {Driver.Manage().Window.Size}");
GoToRegister(); GoToRegister();
Driver.AssertNoError(); Driver.AssertNoError();
} }
/// <summary>
/// Use this ServerUri when trying to browse with selenium
/// Because for some reason, the selenium container can't resolve the tests container domain name
/// </summary>
public Uri ServerUri;
internal IWebElement FindAlertMessage(StatusMessageModel.StatusSeverity severity = StatusMessageModel.StatusSeverity.Success) internal IWebElement FindAlertMessage(StatusMessageModel.StatusSeverity severity = StatusMessageModel.StatusSeverity.Success)
{ {
var className = $"alert-{StatusMessageModel.ToString(severity)}"; var className = $"alert-{StatusMessageModel.ToString(severity)}";
@@ -94,7 +104,7 @@ namespace BTCPayServer.Tests
public string Link(string relativeLink) public string Link(string relativeLink)
{ {
return Server.PayTester.ServerUri.AbsoluteUri.WithoutEndingSlash() + relativeLink.WithStartingSlash(); return ServerUri.AbsoluteUri.WithoutEndingSlash() + relativeLink.WithStartingSlash();
} }
public void GoToRegister() public void GoToRegister()
@@ -275,7 +285,7 @@ namespace BTCPayServer.Tests
public void GoToHome() public void GoToHome()
{ {
Driver.Navigate().GoToUrl(Server.PayTester.ServerUri); Driver.Navigate().GoToUrl(ServerUri);
} }
public void Logout() public void Logout()
@@ -329,7 +339,7 @@ namespace BTCPayServer.Tests
public void GoToLogin() public void GoToLogin()
{ {
Driver.Navigate().GoToUrl(new Uri(Server.PayTester.ServerUri, "/login")); Driver.Navigate().GoToUrl(new Uri(ServerUri, "/login"));
} }
public string CreateInvoice( public string CreateInvoice(
@@ -412,7 +422,7 @@ namespace BTCPayServer.Tests
public void GoToWallet(WalletId walletId = null, WalletsNavPages navPages = WalletsNavPages.Send) public void GoToWallet(WalletId walletId = null, WalletsNavPages navPages = WalletsNavPages.Send)
{ {
walletId ??= WalletId; walletId ??= WalletId;
Driver.Navigate().GoToUrl(new Uri(Server.PayTester.ServerUri, $"wallets/{walletId}")); Driver.Navigate().GoToUrl(new Uri(ServerUri, $"wallets/{walletId}"));
if (navPages != WalletsNavPages.Transactions) if (navPages != WalletsNavPages.Transactions)
{ {
Driver.FindElement(By.Id($"Wallet{navPages}")).Click(); Driver.FindElement(By.Id($"Wallet{navPages}")).Click();
@@ -421,7 +431,7 @@ namespace BTCPayServer.Tests
public void GoToUrl(string relativeUrl) public void GoToUrl(string relativeUrl)
{ {
Driver.Navigate().GoToUrl(new Uri(Server.PayTester.ServerUri, relativeUrl)); Driver.Navigate().GoToUrl(new Uri(ServerUri, relativeUrl));
} }
public void GoToServer(ServerNavPages navPages = ServerNavPages.Index) public void GoToServer(ServerNavPages navPages = ServerNavPages.Index)

View File

@@ -461,7 +461,7 @@ namespace BTCPayServer.Tests
s.FindAlertMessage(); s.FindAlertMessage();
Assert.Contains(pairingCode, s.Driver.PageSource); Assert.Contains(pairingCode, s.Driver.PageSource);
var client = new NBitpayClient.Bitpay(new Key(), s.Server.PayTester.ServerUri); var client = new NBitpayClient.Bitpay(new Key(), s.ServerUri);
await client.AuthorizeClient(new NBitpayClient.PairingCode(pairingCode)); await client.AuthorizeClient(new NBitpayClient.PairingCode(pairingCode));
await client.CreateInvoiceAsync(new NBitpayClient.Invoice() await client.CreateInvoiceAsync(new NBitpayClient.Invoice()
{ {
@@ -470,10 +470,10 @@ namespace BTCPayServer.Tests
FullNotifications = true FullNotifications = true
}, NBitpayClient.Facade.Merchant); }, NBitpayClient.Facade.Merchant);
client = new NBitpayClient.Bitpay(new Key(), s.Server.PayTester.ServerUri); client = new NBitpayClient.Bitpay(new Key(), s.ServerUri);
var code = await client.RequestClientAuthorizationAsync("hehe", NBitpayClient.Facade.Merchant); var code = await client.RequestClientAuthorizationAsync("hehe", NBitpayClient.Facade.Merchant);
s.Driver.Navigate().GoToUrl(code.CreateLink(s.Server.PayTester.ServerUri)); s.Driver.Navigate().GoToUrl(code.CreateLink(s.ServerUri));
s.Driver.FindElement(By.Id("ApprovePairing")).Click(); s.Driver.FindElement(By.Id("ApprovePairing")).Click();
await client.CreateInvoiceAsync(new NBitpayClient.Invoice() await client.CreateInvoiceAsync(new NBitpayClient.Invoice()

View File

@@ -34,6 +34,7 @@ services:
- "80" - "80"
links: links:
- dev - dev
- selenium
extra_hosts: extra_hosts:
- "tests:127.0.0.1" - "tests:127.0.0.1"
volumes: volumes:
@@ -83,6 +84,10 @@ services:
- postgres - postgres
- customer_lnd - customer_lnd
- merchant_lnd - merchant_lnd
selenium:
image: selenium/standalone-chrome:3
expose:
- "4444"
nbxplorer: nbxplorer:
image: nicolasdorier/nbxplorer:2.2.7 image: nicolasdorier/nbxplorer:2.2.7
restart: unless-stopped restart: unless-stopped

View File

@@ -32,6 +32,7 @@ services:
- "80" - "80"
links: links:
- dev - dev
- selenium
extra_hosts: extra_hosts:
- "tests:127.0.0.1" - "tests:127.0.0.1"
volumes: volumes:
@@ -80,6 +81,10 @@ services:
- postgres - postgres
- customer_lnd - customer_lnd
- merchant_lnd - merchant_lnd
selenium:
image: selenium/standalone-chrome:3
expose:
- "4444"
nbxplorer: nbxplorer:
image: nicolasdorier/nbxplorer:2.2.7 image: nicolasdorier/nbxplorer:2.2.7
restart: unless-stopped restart: unless-stopped