1- using Microsoft . VisualStudio . TestTools . UnitTesting ;
2- using OpenQA . Selenium ;
3- using OpenQA . Selenium . Chrome ;
4- using System ;
1+ using System ;
2+ using System . Collections . Generic ;
53using System . IO ;
64using System . Linq ;
5+ using System . Text ;
76using System . Text . Json ;
87using System . Threading . Tasks ;
8+ using Microsoft . Playwright ;
9+ using Microsoft . VisualStudio . TestTools . UnitTesting ;
910using WebExtensions . Net . IntegrationTestsRunner . Helpers ;
1011using WebExtensions . Net . IntegrationTestsRunner . Models ;
1112
@@ -19,7 +20,6 @@ public async Task RunTests()
1920 {
2021 var currentDirectory = AppDomain . CurrentDomain . BaseDirectory ;
2122 var solutionDirectory = currentDirectory [ ..currentDirectory . LastIndexOf ( "\\ test" ) ] ;
22- var driverPath = "C:\\ SeleniumWebDrivers\\ ChromeDriver" ;
2323 var resultsPath = $ "{ solutionDirectory } \\ test\\ TestResults";
2424#if DEBUG
2525 var configuration = "debug" ;
@@ -34,85 +34,87 @@ public async Task RunTests()
3434 Directory . CreateDirectory ( resultsPath ) ;
3535 }
3636
37- if ( ! Directory . Exists ( driverPath ) )
38- {
39- throw new NotSupportedException ( $ "Download the chromedriver from and extract the executable file to { driverPath } . Download the latest version from https://googlechromelabs.github.io/chrome-for-testing/") ;
40- }
41-
4237 try
4338 {
44- using var webDriver = GetWebDriver ( driverPath , extensionPath ) ;
45- await WaitForExtensionPageLoaded ( webDriver ) ;
46- LaunchTestPage ( webDriver ) ;
47- await WaitForTestToFinish ( webDriver ) ;
39+ using var playwright = await Playwright . CreateAsync ( ) ;
40+ var browser = await LaunchBrowser ( playwright , currentDirectory , extensionPath ) ;
41+ var page = await browser . RunAndWaitForPageAsync ( static ( ) => Task . CompletedTask ) ;
42+ var consoleMessages = new List < string > ( ) ;
43+ page . Console += ( _ , message ) =>
44+ {
45+ consoleMessages . Add ( message . Text ) ;
46+ } ;
47+ await LaunchTestPage ( page ) ;
48+ await WaitForTestToFinish ( page , consoleMessages ) ;
4849
4950 // Test results
50- var testResults = GetTestResults ( webDriver ) ;
51+ var testResults = await GetTestResults ( page ) ;
5152 var resultsXML = TestResultsGenerator . Generate ( testResults ) ;
5253 var trxFilePath = $ "{ resultsPath } \\ TestResults_{ DateTime . UtcNow : yyyy-MM-dd_HH_mm_ss} .trx";
5354 await WriteResultsToFile ( trxFilePath , resultsXML ) ;
5455 Console . WriteLine ( $ "Results file: { trxFilePath } ") ;
5556
5657 // Test coverage
57- var testCoverage = await GetTestCoverageHits ( webDriver ) ;
58+ var testCoverage = await GetTestCoverageHits ( page ) ;
5859 if ( testCoverage is not null )
5960 {
6061 TestCoverageWriter . Write ( testCoverage . HitsFilePath , testCoverage . HitsArray ) ;
6162 Console . WriteLine ( $ "Test coverage hits file: { testCoverage . HitsFilePath } ") ;
6263 }
64+
65+ if ( testResults . Status == "failed" )
66+ {
67+ var errors = new StringBuilder ( ) ;
68+ errors . AppendLine ( "One or more test(s) failed." ) ;
69+ var index = 0 ;
70+ foreach ( var testResult in testResults . Tests . Where ( test => test . Status == "failed" ) )
71+ {
72+ index ++ ;
73+ errors . AppendLine (
74+ $ """
75+ // Start Test Result { index } - { testResult . MethodName }
76+ { testResult . FailMessage }
77+ // End Test Result { index } - { testResult . MethodName }
78+ """ ) ;
79+ }
80+ throw new TestRunnerException ( errors . ToString ( ) ) ;
81+ }
6382 }
6483 catch ( TestRunnerException testRunnerException )
6584 {
6685 Assert . Fail ( testRunnerException . Message ) ;
6786 }
68- catch ( Exception exception )
69- {
70- Assert . Fail ( "Failed to create WebDriver. Exception message: " + exception . Message + Environment . NewLine + "Download the latest version from https://googlechromelabs.github.io/chrome-for-testing/" ) ;
71- }
7287 }
7388
74- private static ChromeDriver GetWebDriver ( string driverPath , string extensionPath )
89+ private static Task < IBrowserContext > LaunchBrowser ( IPlaywright playwright , string currentDirectory , string extensionPath )
7590 {
76- var chromeOptions = new ChromeOptions ( ) ;
77- chromeOptions . AddArgument ( $ "load-extension={ extensionPath } ") ;
78- return new ChromeDriver ( driverPath , chromeOptions ) ;
79- }
80-
81- private static async Task WaitForExtensionPageLoaded ( WebDriver webDriver )
82- {
83- await Task . Delay ( 1000 ) ;
84- // wait for 10 seconds
85- var waitTime = 10 * 1000 ;
86- var interval = 500 ;
87- var count = waitTime / interval ;
88- while ( count > 0 )
91+ var userDataDir = Path . Combine ( currentDirectory , "chrome" ) ;
92+ if ( Directory . Exists ( userDataDir ) )
8993 {
90- count -- ;
91- if ( webDriver . WindowHandles . Count == 2 )
92- {
93- webDriver . SwitchTo ( ) . Window ( webDriver . WindowHandles [ 1 ] ) ;
94- break ;
95- }
96- await Task . Delay ( interval ) ;
94+ Directory . Delete ( userDataDir , true ) ;
9795 }
98- if ( ! webDriver . Url . StartsWith ( "chrome-extension://" ) )
99- {
100- webDriver . SwitchTo ( ) . Window ( webDriver . WindowHandles [ 0 ] ) ;
101- }
102- if ( ! webDriver . Url . StartsWith ( "chrome-extension://" ) )
96+ Directory . CreateDirectory ( userDataDir ) ;
97+
98+ return playwright . Chromium . LaunchPersistentContextAsync ( userDataDir , new ( )
10399 {
104- throw new TestRunnerException ( "Failed to wait for extension page to load." ) ;
105- }
100+ Headless = false ,
101+ Channel = "chromium" ,
102+ Args =
103+ [
104+ $ "--disable-extensions-except={ extensionPath } ",
105+ $ "--load-extension={ extensionPath } "
106+ ]
107+ } ) ;
106108 }
107109
108- private static void LaunchTestPage ( WebDriver webDriver )
110+ private static Task LaunchTestPage ( IPage page )
109111 {
110- var extensionUri = new Uri ( webDriver . Url ) ;
112+ var extensionUri = new Uri ( page . Url ) ;
111113 var testPageUrl = $ "{ extensionUri . Scheme } ://{ extensionUri . Host } /tests.html?random=false&coverlet";
112- webDriver . Navigate ( ) . GoToUrl ( testPageUrl ) ;
114+ return page . GotoAsync ( testPageUrl ) ;
113115 }
114116
115- private static async Task WaitForTestToFinish ( WebDriver webDriver )
117+ private static async Task WaitForTestToFinish ( IPage page , IEnumerable < string > consoleMessages )
116118 {
117119 // wait for 30 seconds
118120 var waitTime = 30 * 1000 ;
@@ -124,19 +126,18 @@ private static async Task WaitForTestToFinish(WebDriver webDriver)
124126 while ( count > 0 )
125127 {
126128 count -- ;
127- finished = ( bool ) webDriver . ExecuteScript ( "return window.jsApiReporter && window.jsApiReporter.finished; ") ;
129+ finished = await page . EvaluateAsync < bool > ( " window.jsApiReporter && window.jsApiReporter.finished") ;
128130 if ( finished )
129131 {
130132 break ;
131133 }
132134 await Task . Delay ( interval ) ;
133135 }
136+
134137 if ( ! finished )
135138 {
136- var logs = webDriver . Manage ( ) . Logs
137- . GetLog ( LogType . Browser )
138- . Where ( log => ! log . Message . Contains ( "ThrowExceptionInTest" ) )
139- . Select ( log => log . Message )
139+ var logs = consoleMessages
140+ . Where ( message => ! message . Contains ( "ThrowExceptionInTest" ) )
140141 . ToList ( ) ;
141142 if ( logs . Count > 0 )
142143 {
@@ -146,9 +147,9 @@ private static async Task WaitForTestToFinish(WebDriver webDriver)
146147 }
147148 }
148149
149- private static TestRunInfo GetTestResults ( WebDriver webDriver )
150+ private static async Task < TestRunInfo > GetTestResults ( IPage page )
150151 {
151- var resultsObject = ( string ) webDriver . ExecuteScript ( "return JSON.stringify(TestRunner.GetTestResults()); ") ;
152+ var resultsObject = await page . EvaluateAsync < string > ( " JSON.stringify(TestRunner.GetTestResults())") ;
152153 var testRunResult = JsonSerializer . Deserialize < TestRunInfo > ( resultsObject , new JsonSerializerOptions ( )
153154 {
154155 PropertyNamingPolicy = JsonNamingPolicy . CamelCase
@@ -170,7 +171,7 @@ private static TestRunInfo GetTestResults(WebDriver webDriver)
170171 return testRunResult ;
171172 }
172173
173- private static async Task < TestCoverage > GetTestCoverageHits ( WebDriver webDriver )
174+ private static async Task < TestCoverage > GetTestCoverageHits ( IPage page )
174175 {
175176 // wait for 5 seconds
176177 var waitTime = 5 * 1000 ;
@@ -182,7 +183,7 @@ private static async Task<TestCoverage> GetTestCoverageHits(WebDriver webDriver)
182183 while ( count > 0 )
183184 {
184185 count -- ;
185- var resultsObject = ( string ) webDriver . ExecuteScript ( "return JSON.stringify(TestRunner.GetTestCoverage()); ") ;
186+ var resultsObject = await page . EvaluateAsync < string > ( " JSON.stringify(TestRunner.GetTestCoverage())") ;
186187 testCoverage = JsonSerializer . Deserialize < TestCoverage > ( resultsObject , new JsonSerializerOptions ( )
187188 {
188189 PropertyNamingPolicy = JsonNamingPolicy . CamelCase
0 commit comments