2019-05-21 10:10:07 +02:00
using System ;
2019-09-10 10:03:24 +02:00
using System.Globalization ;
2019-05-13 11:42:20 +02:00
using System.IO ;
2020-06-28 10:55:27 +02:00
using System.Linq ;
using System.Runtime.CompilerServices ;
2021-10-29 08:25:43 +02:00
using System.Threading ;
2019-09-10 10:03:24 +02:00
using System.Threading.Tasks ;
2020-11-17 13:46:23 +01:00
using BTCPayServer.Abstractions.Models ;
2019-09-10 10:03:24 +02:00
using BTCPayServer.Lightning ;
using BTCPayServer.Lightning.CLightning ;
2020-06-28 10:55:27 +02:00
using BTCPayServer.Tests.Logging ;
2020-02-24 14:36:15 +01:00
using BTCPayServer.Views.Manage ;
2020-09-16 08:54:09 +02:00
using BTCPayServer.Views.Server ;
2019-09-10 10:03:24 +02:00
using BTCPayServer.Views.Stores ;
2020-04-28 08:06:28 +02:00
using BTCPayServer.Views.Wallets ;
2021-01-25 17:22:58 +01:00
using Microsoft.Extensions.Configuration ;
2020-06-28 10:55:27 +02:00
using NBitcoin ;
2021-03-01 14:44:53 +01:00
using BTCPayServer.BIP78.Sender ;
2020-06-28 10:55:27 +02:00
using OpenQA.Selenium ;
using OpenQA.Selenium.Chrome ;
using Xunit ;
2021-10-20 07:34:04 +02:00
using OpenQA.Selenium.Support.UI ;
2019-05-13 11:42:20 +02:00
namespace BTCPayServer.Tests
{
public class SeleniumTester : IDisposable
{
2019-09-11 09:22:41 +02:00
public IWebDriver Driver { get ; set ; }
public ServerTester Server { get ; set ; }
2021-01-22 17:49:26 +01:00
public WalletId WalletId { get ; set ; }
2019-05-13 11:42:20 +02:00
2021-01-25 14:10:19 +01:00
public string StoreId { get ; set ; }
2021-01-22 17:49:26 +01:00
public static SeleniumTester Create ( [ CallerMemberNameAttribute ] string scope = null , bool newDb = false ) = >
new SeleniumTester { Server = ServerTester . Create ( scope , newDb ) } ;
2020-01-12 05:54:06 +01:00
2021-02-17 04:14:29 +01:00
public static readonly TimeSpan ImplicitWait = TimeSpan . FromSeconds ( 5 ) ;
2021-01-25 17:22:58 +01:00
2019-10-07 09:04:25 +02:00
public async Task StartAsync ( )
2019-05-13 11:42:20 +02:00
{
2021-09-09 14:51:28 +02:00
Server . PayTester . NoCSP = true ;
2019-10-07 09:04:25 +02:00
await Server . StartAsync ( ) ;
2021-01-25 17:22:58 +01:00
2021-01-25 15:01:53 +01:00
var windowSize = ( Width : 1200 , Height : 1000 ) ;
2021-01-25 17:22:58 +01:00
var builder = new ConfigurationBuilder ( ) ;
2021-01-26 10:22:17 +01:00
builder . AddUserSecrets ( "AB0AC1DD-9D26-485B-9416-56A33F268117" ) ;
2021-01-25 17:22:58 +01:00
var config = builder . Build ( ) ;
// Run `dotnet user-secrets set RunSeleniumInBrowser true` to run tests in browser
var runInBrowser = config [ "RunSeleniumInBrowser" ] = = "true" ;
2021-01-27 09:35:14 +01:00
// Reset this using `dotnet user-secrets remove RunSeleniumInBrowser`
2021-01-25 15:01:53 +01:00
2021-02-17 15:50:04 +01:00
var chromeDriverPath = config [ "ChromeDriverDirectory" ] ? ? ( Server . PayTester . InContainer ? "/usr/bin" : Directory . GetCurrentDirectory ( ) ) ;
2021-02-12 04:21:29 +01:00
2021-01-27 09:35:14 +01:00
var options = new ChromeOptions ( ) ;
if ( ! runInBrowser )
2019-09-10 10:03:24 +02:00
{
2021-01-27 09:35:14 +01:00
options . AddArguments ( "headless" ) ;
2020-01-12 05:54:06 +01:00
}
2021-01-27 09:35:14 +01:00
options . AddArguments ( $"window-size={windowSize.Width}x{windowSize.Height}" ) ;
options . AddArgument ( "shm-size=2g" ) ;
2021-05-19 04:39:27 +02:00
options . AddArgument ( "start-maximized" ) ;
2021-09-22 14:31:44 +02:00
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 ) ;
cds . EnableVerboseLogging = true ;
cds . Port = Utils . FreeTcpPort ( ) ;
cds . HostName = "127.0.0.1" ;
cds . Start ( ) ;
Driver = new ChromeDriver ( cds , options ,
// A bit less than test timeout
TimeSpan . FromSeconds ( 50 ) ) ;
ServerUri = Server . PayTester . ServerUri ;
}
2021-05-19 04:39:27 +02:00
Driver . Manage ( ) . Window . Maximize ( ) ;
2021-01-25 17:22:58 +01:00
2021-01-25 15:01:53 +01:00
Logs . Tester . LogInformation ( $"Selenium: Using {Driver.GetType()}" ) ;
2021-09-22 14:31:44 +02:00
Logs . Tester . LogInformation ( $"Selenium: Browsing to {ServerUri}" ) ;
2019-05-14 15:29:05 +02:00
Logs . Tester . LogInformation ( $"Selenium: Resolution {Driver.Manage().Window.Size}" ) ;
2019-11-06 06:31:45 +01:00
GoToRegister ( ) ;
2019-05-14 11:35:22 +02:00
Driver . AssertNoError ( ) ;
2019-05-13 11:42:20 +02:00
}
2021-10-29 08:25:43 +02:00
2021-09-22 14:31:44 +02:00
/// <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 ;
2021-02-12 04:21:29 +01:00
internal IWebElement FindAlertMessage ( StatusMessageModel . StatusSeverity severity = StatusMessageModel . StatusSeverity . Success )
{
2021-10-18 05:37:59 +02:00
return FindAlertMessage ( new [ ] { severity } ) ;
}
internal IWebElement FindAlertMessage ( params StatusMessageModel . StatusSeverity [ ] severity )
{
var className = string . Join ( ", " , severity . Select ( statusSeverity = > $".alert-{StatusMessageModel.ToString(statusSeverity)}" ) ) ;
var el = Driver . FindElement ( By . CssSelector ( className ) ) ? ? Driver . WaitForElement ( By . CssSelector ( className ) ) ;
2021-02-12 04:21:29 +01:00
if ( el is null )
2021-02-17 04:14:29 +01:00
throw new NoSuchElementException ( $"Unable to find {className}" ) ;
2021-02-12 04:21:29 +01:00
return el ;
}
2019-11-16 07:20:54 +01:00
2019-05-14 16:33:46 +02:00
public string Link ( string relativeLink )
{
2021-09-22 14:31:44 +02:00
return ServerUri . AbsoluteUri . WithoutEndingSlash ( ) + relativeLink . WithStartingSlash ( ) ;
2019-05-14 16:33:46 +02:00
}
2019-05-13 11:42:20 +02:00
2019-11-06 06:31:45 +01:00
public void GoToRegister ( )
{
2021-01-28 10:08:22 +01:00
Driver . Navigate ( ) . GoToUrl ( Link ( "/register" ) ) ;
2019-11-06 06:31:45 +01:00
}
2021-01-22 17:49:26 +01:00
2019-05-13 11:42:20 +02:00
public string RegisterNewUser ( bool isAdmin = false )
{
2019-09-19 12:17:20 +02:00
var usr = RandomUtils . GetUInt256 ( ) . ToString ( ) . Substring ( 64 - 20 ) + "@a.com" ;
2020-06-24 03:34:09 +02:00
Logs . Tester . LogInformation ( $"User: {usr} with password 123456" ) ;
2019-05-13 11:42:20 +02:00
Driver . FindElement ( By . Id ( "Email" ) ) . SendKeys ( usr ) ;
Driver . FindElement ( By . Id ( "Password" ) ) . SendKeys ( "123456" ) ;
Driver . FindElement ( By . Id ( "ConfirmPassword" ) ) . SendKeys ( "123456" ) ;
2019-05-14 16:33:46 +02:00
if ( isAdmin )
Driver . FindElement ( By . Id ( "IsAdmin" ) ) . Click ( ) ;
2019-05-13 11:42:20 +02:00
Driver . FindElement ( By . Id ( "RegisterButton" ) ) . Click ( ) ;
Driver . AssertNoError ( ) ;
return usr ;
}
2021-10-26 13:55:13 +02:00
public ( string storeName , string storeId ) CreateNewStore ( bool keepId = true )
2019-05-13 11:42:20 +02:00
{
2021-03-10 15:53:01 +01:00
Driver . WaitForElement ( By . Id ( "Stores" ) ) . Click ( ) ;
Driver . WaitForElement ( By . Id ( "CreateStore" ) ) . Click ( ) ;
2021-01-22 17:49:26 +01:00
var name = "Store" + RandomUtils . GetUInt64 ( ) ;
2021-03-10 15:53:01 +01:00
Driver . WaitForElement ( By . Id ( "Name" ) ) . SendKeys ( name ) ;
Driver . WaitForElement ( By . Id ( "Create" ) ) . Click ( ) ;
2021-10-29 08:25:43 +02:00
Driver . FindElement ( By . Id ( $"Nav-{StoreNavPages.GeneralSettings.ToString()}" ) ) . Click ( ) ;
2021-10-26 13:55:13 +02:00
var storeId = Driver . WaitForElement ( By . Id ( "Id" ) ) . GetAttribute ( "value" ) ;
2021-10-29 08:25:43 +02:00
Driver . FindElement ( By . Id ( $"Nav-{StoreNavPages.PaymentMethods.ToString()}" ) ) . Click ( ) ;
2021-10-26 13:55:13 +02:00
if ( keepId )
StoreId = storeId ;
return ( name , storeId ) ;
2019-05-13 11:42:20 +02:00
}
2020-04-25 16:11:00 +02:00
public Mnemonic GenerateWallet ( string cryptoCode = "BTC" , string seed = "" , bool importkeys = false , bool privkeys = false , ScriptPubKeyType format = ScriptPubKeyType . Segwit )
2019-12-05 18:56:40 +01:00
{
2021-08-03 07:27:04 +02:00
var isImport = ! string . IsNullOrEmpty ( seed ) ;
2021-01-22 17:49:26 +01:00
Driver . FindElement ( By . Id ( $"Modify{cryptoCode}" ) ) . Click ( ) ;
2021-03-02 11:06:04 +01:00
// Replace previous wallet case
2021-02-17 04:14:29 +01:00
if ( Driver . PageSource . Contains ( "id=\"ChangeWalletLink\"" ) )
2021-02-11 11:48:54 +01:00
{
2021-02-17 04:14:29 +01:00
Driver . FindElement ( By . Id ( "ChangeWalletLink" ) ) . Click ( ) ;
2021-09-07 04:55:53 +02:00
Driver . WaitForElement ( By . Id ( "ConfirmInput" ) ) . SendKeys ( "REPLACE" ) ;
Driver . FindElement ( By . Id ( "ConfirmContinue" ) ) . Click ( ) ;
2021-02-11 11:48:54 +01:00
}
2021-08-03 07:27:04 +02:00
if ( isImport )
2021-02-11 11:48:54 +01:00
{
Logs . Tester . LogInformation ( "Progressing with existing seed" ) ;
2021-02-17 04:14:29 +01:00
Driver . FindElement ( By . Id ( "ImportWalletOptionsLink" ) ) . Click ( ) ;
Driver . FindElement ( By . Id ( "ImportSeedLink" ) ) . Click ( ) ;
2021-02-11 11:48:54 +01:00
Driver . FindElement ( By . Id ( "ExistingMnemonic" ) ) . SendKeys ( seed ) ;
2021-02-17 04:14:29 +01:00
Driver . SetCheckbox ( By . Id ( "SavePrivateKeys" ) , privkeys ) ;
2021-02-11 11:48:54 +01:00
}
2021-08-03 07:27:04 +02:00
else
{
var option = privkeys ? "Hotwallet" : "Watchonly" ;
Logs . Tester . LogInformation ( $"Generating new seed ({option})" ) ;
Driver . FindElement ( By . Id ( "GenerateWalletLink" ) ) . Click ( ) ;
Driver . FindElement ( By . Id ( $"Generate{option}Link" ) ) . Click ( ) ;
}
2021-02-11 11:48:54 +01:00
2021-01-22 17:49:26 +01:00
Driver . FindElement ( By . Id ( "ScriptPubKeyType" ) ) . Click ( ) ;
Driver . FindElement ( By . CssSelector ( $"#ScriptPubKeyType option[value={format}]" ) ) . Click ( ) ;
2021-05-19 04:39:27 +02:00
Driver . ToggleCollapse ( "AdvancedSettings" ) ;
2021-02-17 15:50:04 +01:00
Driver . SetCheckbox ( By . Id ( "ImportKeysToRPC" ) , importkeys ) ;
2021-02-17 12:34:49 +01:00
Driver . FindElement ( By . Id ( "Continue" ) ) . Click ( ) ;
2021-02-11 11:48:54 +01:00
2021-08-03 07:27:04 +02:00
if ( isImport )
2019-12-05 18:56:40 +01:00
{
2021-08-03 07:27:04 +02:00
// Confirm addresses
Driver . FindElement ( By . Id ( "Confirm" ) ) . Click ( ) ;
2019-12-05 18:56:40 +01:00
}
2021-08-03 07:27:04 +02:00
else
{
// Seed backup
FindAlertMessage ( ) ;
if ( string . IsNullOrEmpty ( seed ) )
{
seed = Driver . FindElements ( By . Id ( "RecoveryPhrase" ) ) . First ( ) . GetAttribute ( "data-mnemonic" ) ;
}
// Confirm seed backup
Driver . FindElement ( By . Id ( "confirm" ) ) . Click ( ) ;
Driver . FindElement ( By . Id ( "submit" ) ) . Click ( ) ;
}
2020-06-24 03:34:09 +02:00
WalletId = new WalletId ( StoreId , cryptoCode ) ;
2020-03-23 07:46:54 +01:00
return new Mnemonic ( seed ) ;
2019-12-05 18:56:40 +01:00
}
2021-01-22 17:49:26 +01:00
2019-09-10 10:03:24 +02:00
public void AddDerivationScheme ( string cryptoCode = "BTC" , string derivationScheme = "xpub661MyMwAqRbcGABgHMUXDzPzH1tU7eZaAaJQXhDXsSxsqyQzQeU6kznNfSuAyqAK9UaWSaZaMFdNiY5BCF4zBPAzSnwfUAwUhwttuAKwfRX-[legacy]" )
2019-05-13 11:42:20 +02:00
{
2021-01-22 17:49:26 +01:00
Driver . FindElement ( By . Id ( $"Modify{cryptoCode}" ) ) . Click ( ) ;
2021-02-17 04:14:29 +01:00
Driver . FindElement ( By . Id ( "ImportWalletOptionsLink" ) ) . Click ( ) ;
Driver . FindElement ( By . Id ( "ImportXpubLink" ) ) . Click ( ) ;
2021-02-11 11:48:54 +01:00
Driver . FindElement ( By . Id ( "DerivationScheme" ) ) . SendKeys ( derivationScheme ) ;
2021-01-22 17:49:26 +01:00
Driver . FindElement ( By . Id ( "Continue" ) ) . Click ( ) ;
2021-01-25 14:10:19 +01:00
Driver . FindElement ( By . Id ( "Confirm" ) ) . Click ( ) ;
2021-01-22 17:49:26 +01:00
FindAlertMessage ( ) ;
2019-05-13 11:42:20 +02:00
}
2020-01-12 05:54:06 +01:00
2021-10-29 08:25:43 +02:00
public void AddLightningNode ( string cryptoCode = "BTC" , LightningConnectionType ? connectionType = null , bool test = true )
2019-09-10 10:03:24 +02:00
{
2021-03-31 13:23:36 +02:00
Driver . FindElement ( By . Id ( $"Modify-Lightning{cryptoCode}" ) ) . Click ( ) ;
2021-10-29 08:25:43 +02:00
if ( Driver . PageSource . Contains ( "id=\"SetupLightningNodeLink\"" ) )
{
Driver . FindElement ( By . Id ( $"SetupLightningNodeLink" ) ) . Click ( ) ;
}
2021-03-31 13:23:36 +02:00
var connectionString = connectionType switch
{
LightningConnectionType . Charge = >
$"type=charge;server={Server.MerchantCharge.Client.Uri.AbsoluteUri};allowinsecure=true" ,
LightningConnectionType . CLightning = >
$"type=clightning;server={((CLightningClient) Server.MerchantLightningD).Address.AbsoluteUri}" ,
LightningConnectionType . LndREST = >
$"type=lnd-rest;server={Server.MerchantLnd.Swagger.BaseUrl};allowinsecure=true" ,
_ = > null
} ;
if ( connectionString = = null )
{
Assert . True ( Driver . FindElement ( By . Id ( "LightningNodeType-Internal" ) ) . Enabled , "Usage of the internal Lightning node is disabled." ) ;
Driver . FindElement ( By . CssSelector ( "label[for=\"LightningNodeType-Internal\"]" ) ) . Click ( ) ;
}
2019-09-10 10:03:24 +02:00
else
2021-03-31 13:23:36 +02:00
{
Driver . FindElement ( By . CssSelector ( "label[for=\"LightningNodeType-Custom\"]" ) ) . Click ( ) ;
2021-10-26 13:55:13 +02:00
Driver . FindElement ( By . Id ( "ConnectionString" ) ) . Clear ( ) ;
2021-03-31 13:23:36 +02:00
Driver . FindElement ( By . Id ( "ConnectionString" ) ) . SendKeys ( connectionString ) ;
2021-10-26 13:55:13 +02:00
if ( test )
{
Driver . FindElement ( By . Id ( "test" ) ) . Click ( ) ;
Assert . Contains ( "Connection to the Lightning node successful." , FindAlertMessage ( ) . Text ) ;
}
2021-04-19 16:21:50 +02:00
}
2021-03-31 13:23:36 +02:00
2021-04-20 12:23:50 +02:00
Driver . FindElement ( By . Id ( "save" ) ) . Click ( ) ;
2021-04-20 03:55:41 +02:00
Assert . Contains ( $"{cryptoCode} Lightning node updated." , FindAlertMessage ( ) . Text ) ;
2021-04-16 15:31:09 +02:00
var enabled = Driver . FindElement ( By . Id ( $"{cryptoCode}LightningEnabled" ) ) ;
if ( enabled . Text = = "Enable" )
{
enabled . Click ( ) ;
Assert . Contains ( $"{cryptoCode} Lightning payments are now enabled for this store." , FindAlertMessage ( ) . Text ) ;
}
2019-09-10 10:03:24 +02:00
}
2019-05-13 11:42:20 +02:00
public void ClickOnAllSideMenus ( )
{
2021-04-08 15:32:42 +02:00
var links = Driver . FindElements ( By . CssSelector ( ".nav .nav-link" ) ) . Select ( c = > c . GetAttribute ( "href" ) ) . ToList ( ) ;
2019-05-15 09:00:03 +02:00
Driver . AssertNoError ( ) ;
2019-05-13 11:42:20 +02:00
foreach ( var l in links )
{
2019-10-31 04:29:59 +01:00
Logs . Tester . LogInformation ( $"Checking no error on {l}" ) ;
2019-05-13 11:42:20 +02:00
Driver . Navigate ( ) . GoToUrl ( l ) ;
Driver . AssertNoError ( ) ;
}
}
public void Dispose ( )
{
if ( Driver ! = null )
{
try
{
2021-01-22 17:49:26 +01:00
Driver . Quit ( ) ;
2019-05-13 11:42:20 +02:00
}
2021-01-25 14:10:19 +01:00
catch
{
// ignored
}
2019-05-13 11:42:20 +02:00
Driver . Dispose ( ) ;
}
2021-01-25 14:10:19 +01:00
Server ? . Dispose ( ) ;
2019-05-13 11:42:20 +02:00
}
2019-05-14 16:33:46 +02:00
internal void AssertNotFound ( )
{
2020-02-01 09:29:08 +01:00
Assert . Contains ( "404 - Page not found</h1>" , Driver . PageSource ) ;
2019-05-14 16:33:46 +02:00
}
2019-07-01 05:39:25 +02:00
public void GoToHome ( )
2019-05-14 16:33:46 +02:00
{
2021-09-22 14:31:44 +02:00
Driver . Navigate ( ) . GoToUrl ( ServerUri ) ;
2019-05-14 16:33:46 +02:00
}
2019-07-01 05:39:25 +02:00
public void Logout ( )
2019-05-14 16:33:46 +02:00
{
Driver . FindElement ( By . Id ( "Logout" ) ) . Click ( ) ;
}
2019-07-01 05:39:25 +02:00
public void Login ( string user , string password )
{
Driver . FindElement ( By . Id ( "Email" ) ) . SendKeys ( user ) ;
Driver . FindElement ( By . Id ( "Password" ) ) . SendKeys ( password ) ;
Driver . FindElement ( By . Id ( "LoginButton" ) ) . Click ( ) ;
2020-10-17 22:53:07 +02:00
}
2021-10-29 10:27:33 +02:00
public void GoToApps ( )
{
Driver . FindElement ( By . Id ( "Apps" ) ) . Click ( ) ;
}
2020-10-17 22:53:07 +02:00
public void GoToStores ( )
{
Driver . FindElement ( By . Id ( "Stores" ) ) . Click ( ) ;
2019-07-01 05:39:25 +02:00
}
2019-09-03 13:11:36 +02:00
2021-10-29 08:25:43 +02:00
public void GoToStore ( string storeId , StoreNavPages storeNavPage = StoreNavPages . PaymentMethods )
2019-09-03 13:11:36 +02:00
{
2021-10-22 04:17:40 +02:00
GoToHome ( ) ;
Driver . WaitForAndClick ( By . Id ( "Stores" ) ) ;
2019-09-03 13:11:36 +02:00
Driver . FindElement ( By . Id ( $"update-store-{storeId}" ) ) . Click ( ) ;
2021-01-22 17:49:26 +01:00
2021-10-29 08:25:43 +02:00
if ( storeNavPage ! = StoreNavPages . PaymentMethods )
2019-09-10 10:03:24 +02:00
{
2021-10-29 08:25:43 +02:00
Driver . FindElement ( By . Id ( $"Nav-{storeNavPage.ToString()}" ) ) . Click ( ) ;
2019-09-10 10:03:24 +02:00
}
2019-09-03 13:11:36 +02:00
}
2020-01-12 05:54:06 +01:00
2019-09-03 13:11:36 +02:00
public void GoToInvoiceCheckout ( string invoiceId )
{
Driver . FindElement ( By . Id ( "Invoices" ) ) . Click ( ) ;
Driver . FindElement ( By . Id ( $"invoice-checkout-{invoiceId}" ) ) . Click ( ) ;
2019-09-10 10:03:24 +02:00
CheckForJSErrors ( ) ;
2019-09-03 13:11:36 +02:00
}
2020-01-12 05:54:06 +01:00
2019-09-10 10:03:24 +02:00
public void GoToInvoices ( )
{
Driver . FindElement ( By . Id ( "Invoices" ) ) . Click ( ) ;
}
2020-06-28 10:55:27 +02:00
public void GoToProfile ( ManageNavPages navPages = ManageNavPages . Index )
2020-02-24 14:36:15 +01:00
{
Driver . FindElement ( By . Id ( "MySettings" ) ) . Click ( ) ;
if ( navPages ! = ManageNavPages . Index )
{
Driver . FindElement ( By . Id ( navPages . ToString ( ) ) ) . Click ( ) ;
}
}
public void GoToLogin ( )
{
2021-09-22 14:31:44 +02:00
Driver . Navigate ( ) . GoToUrl ( new Uri ( ServerUri , "/login" ) ) ;
2020-02-24 14:36:15 +01:00
}
2019-09-10 10:03:24 +02:00
2021-09-01 05:21:44 +02:00
public string CreateInvoice (
string storeName ,
decimal? amount = 100 ,
string currency = "USD" ,
string refundEmail = "" ,
2021-10-26 13:55:13 +02:00
string defaultPaymentMethod = null ,
2021-10-27 16:32:56 +02:00
bool? requiresRefundEmail = null ,
2021-10-26 13:55:13 +02:00
StatusMessageModel . StatusSeverity expectedSeverity = StatusMessageModel . StatusSeverity . Success
2021-09-01 05:21:44 +02:00
)
2019-09-10 10:03:24 +02:00
{
GoToInvoices ( ) ;
2021-01-22 17:49:26 +01:00
Driver . FindElement ( By . Id ( "CreateNewInvoice" ) ) . Click ( ) ;
2021-08-03 10:03:00 +02:00
if ( amount is decimal v )
Driver . FindElement ( By . Id ( "Amount" ) ) . SendKeys ( v . ToString ( CultureInfo . InvariantCulture ) ) ;
2019-09-10 10:03:24 +02:00
var currencyEl = Driver . FindElement ( By . Id ( "Currency" ) ) ;
currencyEl . Clear ( ) ;
currencyEl . SendKeys ( currency ) ;
Driver . FindElement ( By . Id ( "BuyerEmail" ) ) . SendKeys ( refundEmail ) ;
2020-09-17 11:37:49 +02:00
Driver . FindElement ( By . Name ( "StoreId" ) ) . SendKeys ( storeName ) ;
2021-10-20 07:34:04 +02:00
if ( defaultPaymentMethod is string )
new SelectElement ( Driver . FindElement ( By . Name ( "DefaultPaymentMethod" ) ) ) . SelectByValue ( defaultPaymentMethod ) ;
2021-10-27 16:32:56 +02:00
if ( requiresRefundEmail is bool )
new SelectElement ( Driver . FindElement ( By . Name ( "RequiresRefundEmail" ) ) ) . SelectByValue ( requiresRefundEmail = = true ? "1" : "2" ) ;
2020-09-17 11:37:49 +02:00
Driver . FindElement ( By . Id ( "Create" ) ) . Click ( ) ;
2021-10-26 13:55:13 +02:00
var statusElement = FindAlertMessage ( expectedSeverity ) ;
return expectedSeverity = = StatusMessageModel . StatusSeverity . Success ? statusElement . Text . Split ( " " ) [ 1 ] : null ;
2019-09-10 10:03:24 +02:00
}
2020-06-24 03:34:09 +02:00
public async Task FundStoreWallet ( WalletId walletId = null , int coins = 1 , decimal denomination = 1 m )
2020-03-30 08:31:30 +02:00
{
2020-06-24 03:34:09 +02:00
walletId ? ? = WalletId ;
2020-04-28 08:06:28 +02:00
GoToWallet ( walletId , WalletsNavPages . Receive ) ;
2020-03-30 08:31:30 +02:00
Driver . FindElement ( By . Id ( "generateButton" ) ) . Click ( ) ;
2020-12-22 03:18:51 +01:00
var addressStr = Driver . FindElement ( By . Id ( "address" ) ) . GetProperty ( "value" ) ;
2020-03-30 08:31:30 +02:00
var address = BitcoinAddress . Create ( addressStr , ( ( BTCPayNetwork ) Server . NetworkProvider . GetNetwork ( walletId . CryptoCode ) ) . NBitcoinNetwork ) ;
2021-01-22 17:49:26 +01:00
for ( var i = 0 ; i < coins ; i + + )
2020-03-30 08:31:30 +02:00
{
await Server . ExplorerNode . SendToAddressAsync ( address , Money . Coins ( denomination ) ) ;
}
}
2020-06-28 10:55:27 +02:00
2020-03-30 08:31:30 +02:00
public void PayInvoice ( WalletId walletId , string invoiceId )
{
GoToInvoiceCheckout ( invoiceId ) ;
var bip21 = Driver . FindElement ( By . ClassName ( "payment__details__instruction__open-wallet__btn" ) )
. GetAttribute ( "href" ) ;
2020-04-07 14:18:56 +02:00
Assert . Contains ( $"{PayjoinClient.BIP21EndpointKey}" , bip21 ) ;
2020-06-28 10:55:27 +02:00
2021-01-25 14:10:19 +01:00
GoToWallet ( walletId ) ;
2020-03-30 08:31:30 +02:00
Driver . FindElement ( By . Id ( "bip21parse" ) ) . Click ( ) ;
Driver . SwitchTo ( ) . Alert ( ) . SendKeys ( bip21 ) ;
Driver . SwitchTo ( ) . Alert ( ) . Accept ( ) ;
2021-06-14 07:06:56 +02:00
Driver . FindElement ( By . Id ( "SignTransaction" ) ) . Click ( ) ;
Driver . FindElement ( By . Id ( "SignWithSeed" ) ) . Click ( ) ;
2021-01-22 17:49:26 +01:00
Driver . FindElement ( By . CssSelector ( "button[value=broadcast]" ) ) . Click ( ) ;
2020-03-30 08:31:30 +02:00
}
2019-09-10 10:03:24 +02:00
private void CheckForJSErrors ( )
{
//wait for seleniun update: https://stackoverflow.com/questions/57520296/selenium-webdriver-3-141-0-driver-manage-logs-availablelogtypes-throwing-syste
2021-04-19 16:21:50 +02:00
// var errorStrings = new List<string>
// {
// "SyntaxError",
// "EvalError",
// "ReferenceError",
// "RangeError",
// "TypeError",
// "URIError"
2020-01-12 05:54:06 +01:00
// };
//
// var jsErrors = Driver.Manage().Logs.GetLog(LogType.Browser).Where(x => errorStrings.Any(e => x.Message.Contains(e)));
//
// if (jsErrors.Any())
// {
// Logs.Tester.LogInformation("JavaScript error(s):" + Environment.NewLine + jsErrors.Aggregate("", (s, entry) => s + entry.Message + Environment.NewLine));
// }
// Assert.Empty(jsErrors);
2019-09-10 10:03:24 +02:00
}
2020-06-24 03:34:09 +02:00
public void GoToWallet ( WalletId walletId = null , WalletsNavPages navPages = WalletsNavPages . Send )
2020-03-23 07:46:54 +01:00
{
2020-06-24 03:34:09 +02:00
walletId ? ? = WalletId ;
2021-09-22 14:31:44 +02:00
Driver . Navigate ( ) . GoToUrl ( new Uri ( ServerUri , $"wallets/{walletId}" ) ) ;
2020-04-28 08:06:28 +02:00
if ( navPages ! = WalletsNavPages . Transactions )
{
Driver . FindElement ( By . Id ( $"Wallet{navPages}" ) ) . Click ( ) ;
}
2020-03-23 07:46:54 +01:00
}
2020-10-05 09:39:49 +02:00
public void GoToUrl ( string relativeUrl )
{
2021-09-22 14:31:44 +02:00
Driver . Navigate ( ) . GoToUrl ( new Uri ( ServerUri , relativeUrl ) ) ;
2020-10-05 09:39:49 +02:00
}
2021-04-19 16:21:50 +02:00
2020-09-16 08:54:09 +02:00
public void GoToServer ( ServerNavPages navPages = ServerNavPages . Index )
{
Driver . FindElement ( By . Id ( "ServerSettings" ) ) . Click ( ) ;
if ( navPages ! = ServerNavPages . Index )
{
Driver . FindElement ( By . Id ( $"Server-{navPages}" ) ) . Click ( ) ;
}
}
2020-06-24 10:51:00 +02:00
public void GoToInvoice ( string id )
{
GoToInvoices ( ) ;
2020-06-28 10:55:27 +02:00
foreach ( var el in Driver . FindElements ( By . ClassName ( "invoice-details-link" ) ) )
2020-06-24 10:51:00 +02:00
{
if ( el . GetAttribute ( "href" ) . Contains ( id , StringComparison . OrdinalIgnoreCase ) )
{
el . Click ( ) ;
break ;
}
}
}
2019-05-13 11:42:20 +02:00
}
}