Skip to content

Commit 2b1ba31

Browse files
authored
Introduce protocol in launch options (#2578)
* Introduce protocol in launch options * code style * Add protocol to browser class
1 parent b1e8bec commit 2b1ba31

File tree

16 files changed

+158
-96
lines changed

16 files changed

+158
-96
lines changed

.github/workflows/dotnet.yml

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ env:
2020

2121
jobs:
2222
build:
23-
name: build-${{ matrix.browser }}-${{ matrix.mode }}-${{ matrix.os }}
23+
name: build-${{ matrix.browser }}-${{ matrix.mode }}-${{ matrix.os }}-${{ matrix.protocol }}
2424
runs-on: ${{ matrix.os }}
2525
strategy:
2626
fail-fast: false
@@ -29,33 +29,63 @@ jobs:
2929
- os: ubuntu-latest
3030
browser: CHROME
3131
mode: headless
32+
protocol: cdp
3233
- os: ubuntu-latest
3334
browser: CHROME
3435
mode: headful
36+
protocol: cdp
3537
- os: ubuntu-latest
3638
browser: CHROME
3739
mode: headless-shell
40+
protocol: cdp
3841
- os: ubuntu-latest
3942
browser: FIREFOX
4043
mode: headless
44+
protocol: cdp
4145
- os: ubuntu-latest
4246
browser: FIREFOX
4347
mode: headful
48+
protocol: cdp
4449
- os: windows-latest
4550
browser: CHROME
4651
mode: headless
52+
protocol: cdp
4753
- os: windows-latest
4854
browser: CHROME
4955
mode: headful
56+
protocol: cdp
5057
- os: windows-latest
5158
browser: CHROME
5259
mode: headless-shell
60+
protocol: cdp
5361
- os: windows-latest
5462
browser: FIREFOX
5563
mode: headless
64+
protocol: cdp
5665
- os: windows-latest
5766
browser: FIREFOX
5867
mode: headful
68+
protocol: cdp
69+
- os: ubuntu-latest
70+
browser: CHROME
71+
mode: headless
72+
protocol: webdriverbidi
73+
- os: ubuntu-latest
74+
browser: CHROME
75+
mode: headful
76+
protocol: webdriverbidi
77+
- os: ubuntu-latest
78+
browser: CHROME
79+
mode: headless-shell
80+
protocol: webdriverbidi
81+
- os: ubuntu-latest
82+
browser: FIREFOX
83+
mode: headless
84+
protocol: webdriverbidi
85+
- os: ubuntu-latest
86+
browser: FIREFOX
87+
mode: headful
88+
protocol: webdriverbidi
5989
steps:
6090
- uses: actions/checkout@v3
6191
- name: Setup .NET Core
@@ -83,7 +113,7 @@ jobs:
83113
New-SelfSignedCertificate -Subject "localhost" -FriendlyName "Puppeteer" -CertStoreLocation "cert:\CurrentUser\My"
84114
Get-ChildItem -Path cert:\CurrentUSer\my | where { $_.friendlyname -eq "Puppeteer" } | Export-Certificate -FilePath $env:GITHUB_WORKSPACE\lib\PuppeteerSharp.TestServer\testCert.cer
85115
- name: Check formatting
86-
if: ${{ matrix.os == 'ubuntu-latest' && matrix.browser == 'CHROME' && matrix.mode == 'headless' }}
116+
if: ${{ matrix.os == 'ubuntu-latest' && matrix.browser == 'CHROME' && matrix.mode == 'headless' && matrix.protocol == 'cdp' }}
87117
run: dotnet format ./lib/PuppeteerSharp.sln --verify-no-changes
88118
- name: Build
89119
working-directory: lib
@@ -93,6 +123,7 @@ jobs:
93123
env:
94124
PRODUCT: ${{ matrix.browser }}
95125
HEADLESS_MODE: ${{ matrix.mode }}
126+
PROTOCOL: ${{ matrix.protocol }}
96127
run: |
97128
Xvfb :1 -screen 5 1024x768x8 &
98129
export DISPLAY=:1.5
@@ -103,6 +134,7 @@ jobs:
103134
env:
104135
PRODUCT: ${{ matrix.browser }}
105136
HEADLESS_MODE: ${{ matrix.mode }}
137+
PROTOCOL: ${{ matrix.protocol }}
106138
run: |
107139
cd .\lib\PuppeteerSharp.Tests
108140
dotnet test -s test.runsettings --blame-hang-timeout 300000

lib/PuppeteerSharp.Nunit/PuppeteerTestAttribute.cs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,7 @@ public class PuppeteerTestAttribute : NUnitAttribute, IApplyToTest
2121
private static TestExpectation[] _localExpectations;
2222
private static TestExpectation[] _upstreamExpectations;
2323
public static readonly bool IsChrome = Environment.GetEnvironmentVariable("PRODUCT") != "FIREFOX";
24-
// TODO: Change implementation when we implement Webdriver Bidi
25-
public static readonly bool IsCdp = true;
24+
public static readonly bool IsCdp = Environment.GetEnvironmentVariable("PROTOCOL") != "webdriverbidi";
2625
public static readonly HeadlessMode Headless =
2726
string.IsNullOrEmpty(Environment.GetEnvironmentVariable("HEADLESS_MODE")) ?
2827
(System.Diagnostics.Debugger.IsAttached ? HeadlessMode.False : HeadlessMode.True) :

lib/PuppeteerSharp.Tests/BrowserContextTests/BrowserContextTests.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,8 @@ public async Task ShouldWorkAcrossSessions()
142142

143143
var remoteBrowser = await Puppeteer.ConnectAsync(new ConnectOptions
144144
{
145-
BrowserWSEndpoint = Browser.WebSocketEndpoint
145+
BrowserWSEndpoint = Browser.WebSocketEndpoint,
146+
Protocol = ((Browser)Browser).Protocol,
146147
});
147148
var contexts = remoteBrowser.BrowserContexts();
148149
Assert.AreEqual(2, contexts.Length);

lib/PuppeteerSharp.Tests/BrowserTests/IsConnectedTests.cs

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,16 +6,13 @@ namespace PuppeteerSharp.Tests.BrowserTests
66
{
77
public class IsConnectedTests : PuppeteerBrowserBaseTest
88
{
9-
public IsConnectedTests() : base()
10-
{
11-
}
12-
139
[Test, Retry(2), PuppeteerTest("browser.spec", "Browser.isConnected", "should set the browser connected state")]
1410
public async Task ShouldSetTheBrowserConnectedState()
1511
{
1612
var newBrowser = await Puppeteer.ConnectAsync(new ConnectOptions
1713
{
18-
BrowserWSEndpoint = Browser.WebSocketEndpoint
14+
BrowserWSEndpoint = Browser.WebSocketEndpoint,
15+
Protocol = ((Browser)Browser).Protocol,
1916
});
2017
Assert.True(newBrowser.IsConnected);
2118
newBrowser.Disconnect();

lib/PuppeteerSharp.Tests/BrowserTests/ProcessTests.cs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,6 @@ namespace PuppeteerSharp.Tests.BrowserTests
66
{
77
public class ProcessTests : PuppeteerBrowserBaseTest
88
{
9-
public ProcessTests() : base() { }
10-
119
[Test, Retry(2), PuppeteerTest("browser.spec", "Browser.process", "should return child_process instance")]
1210
public void ShouldReturnProcessInstance()
1311
{
@@ -20,7 +18,12 @@ public async Task ShouldNotReturnChildProcessForRemoteBrowser()
2018
{
2119
var browserWSEndpoint = Browser.WebSocketEndpoint;
2220
var remoteBrowser = await Puppeteer.ConnectAsync(
23-
new ConnectOptions { BrowserWSEndpoint = browserWSEndpoint }, TestConstants.LoggerFactory);
21+
new ConnectOptions
22+
{
23+
BrowserWSEndpoint = browserWSEndpoint,
24+
Protocol = ((Browser)Browser).Protocol,
25+
},
26+
TestConstants.LoggerFactory);
2427
Assert.Null(remoteBrowser.Process);
2528
remoteBrowser.Disconnect();
2629
}

lib/PuppeteerSharp.Tests/LauncherTests/BrowserCloseTests.cs

Lines changed: 15 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -6,30 +6,28 @@ namespace PuppeteerSharp.Tests.BrowserTests.Events
66
{
77
public class BrowserCloseTests : PuppeteerBrowserBaseTest
88
{
9-
public BrowserCloseTests() : base()
10-
{
11-
}
12-
139
[Test, Retry(2), PuppeteerTest("launcher.spec", "Launcher specs Browser.close", "should terminate network waiters")]
1410
public async Task ShouldTerminateNetworkWaiters()
1511
{
16-
await using (var browser = await Puppeteer.LaunchAsync(TestConstants.DefaultBrowserOptions()))
17-
await using (var remote = await Puppeteer.ConnectAsync(new ConnectOptions { BrowserWSEndpoint = browser.WebSocketEndpoint }))
12+
await using var browser = await Puppeteer.LaunchAsync(TestConstants.DefaultBrowserOptions());
13+
await using var remote = await Puppeteer.ConnectAsync(new ConnectOptions
1814
{
19-
var newPage = await remote.NewPageAsync();
20-
var requestTask = newPage.WaitForRequestAsync(TestConstants.EmptyPage);
21-
var responseTask = newPage.WaitForResponseAsync(TestConstants.EmptyPage);
15+
BrowserWSEndpoint = browser.WebSocketEndpoint,
16+
Protocol = ((Browser)browser).Protocol,
17+
});
18+
var newPage = await remote.NewPageAsync();
19+
var requestTask = newPage.WaitForRequestAsync(TestConstants.EmptyPage);
20+
var responseTask = newPage.WaitForResponseAsync(TestConstants.EmptyPage);
2221

23-
await browser.CloseAsync();
22+
await browser.CloseAsync();
2423

25-
var exception = Assert.ThrowsAsync<TargetClosedException>(() => requestTask);
26-
StringAssert.Contains("Target closed", exception.Message);
27-
StringAssert.DoesNotContain("Timeout", exception.Message);
24+
var exception = Assert.ThrowsAsync<TargetClosedException>(() => requestTask);
25+
StringAssert.Contains("Target closed", exception.Message);
26+
StringAssert.DoesNotContain("Timeout", exception.Message);
2827

29-
exception = Assert.ThrowsAsync<TargetClosedException>(() => responseTask);
30-
StringAssert.Contains("Target closed", exception.Message);
31-
StringAssert.DoesNotContain("Timeout", exception.Message);
32-
}
28+
exception = Assert.ThrowsAsync<TargetClosedException>(() => responseTask);
29+
StringAssert.Contains("Target closed", exception.Message);
30+
StringAssert.DoesNotContain("Timeout", exception.Message);
3331
}
3432
}
3533
}

lib/PuppeteerSharp.Tests/LauncherTests/BrowserDisconnectTests.cs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,8 @@ public async Task ShouldRejectNavigationWhenBrowserCloses()
1515
await using var browser = await Puppeteer.LaunchAsync(TestConstants.DefaultBrowserOptions());
1616
var remote = await Puppeteer.ConnectAsync(new ConnectOptions
1717
{
18-
BrowserWSEndpoint = browser.WebSocketEndpoint
18+
BrowserWSEndpoint = browser.WebSocketEndpoint,
19+
Protocol = ((Browser)Browser).Protocol,
1920
});
2021
var page = await remote.NewPageAsync();
2122
var navigationTask = page.GoToAsync(TestConstants.ServerUrl + "/one-style.html", new NavigationOptions
@@ -41,7 +42,8 @@ public async Task ShouldRejectWaitForSelectorWhenBrowserCloses()
4142
await using var browser = await Puppeteer.LaunchAsync(TestConstants.DefaultBrowserOptions());
4243
var remote = await Puppeteer.ConnectAsync(new ConnectOptions
4344
{
44-
BrowserWSEndpoint = browser.WebSocketEndpoint
45+
BrowserWSEndpoint = browser.WebSocketEndpoint,
46+
Protocol = ((Browser)browser).Protocol,
4547
});
4648
var page = await remote.NewPageAsync();
4749
var watchdog = page.WaitForSelectorAsync("div", new WaitForSelectorOptions { Timeout = 60000 });

lib/PuppeteerSharp.Tests/LauncherTests/BrowserEventsDisconnectedTests.cs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,11 @@ public BrowserEventsDisconnectedTests() : base()
1414
public async Task ShouldEmittedWhenBrowserGetsClosedDisconnectedOrUnderlyingWebsocketGetsClosed()
1515
{
1616
var originalBrowser = await Puppeteer.LaunchAsync(TestConstants.DefaultBrowserOptions(), TestConstants.LoggerFactory);
17-
var connectOptions = new ConnectOptions { BrowserWSEndpoint = originalBrowser.WebSocketEndpoint };
17+
var connectOptions = new ConnectOptions
18+
{
19+
BrowserWSEndpoint = originalBrowser.WebSocketEndpoint,
20+
Protocol = ((Browser)Browser).Protocol,
21+
};
1822
var remoteBrowser1 = await Puppeteer.ConnectAsync(connectOptions, TestConstants.LoggerFactory);
1923
var remoteBrowser2 = await Puppeteer.ConnectAsync(connectOptions, TestConstants.LoggerFactory);
2024

lib/PuppeteerSharp.Tests/LauncherTests/PuppeteerConnectTests.cs

Lines changed: 32 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
using System;
21
using System.Linq;
32
using System.Threading.Tasks;
43
using Microsoft.AspNetCore.Connections.Features;
@@ -11,16 +10,13 @@ namespace PuppeteerSharp.Tests.LauncherTests
1110
{
1211
public class PuppeteerConnectTests : PuppeteerBrowserBaseTest
1312
{
14-
public PuppeteerConnectTests() : base()
15-
{
16-
}
17-
1813
[Test, Retry(2), PuppeteerTest("launcher.spec", "Launcher specs Puppeteer Puppeteer.connect", "should be able to connect multiple times to the same browser")]
1914
public async Task ShouldBeAbleToConnectMultipleTimesToSameBrowser()
2015
{
2116
var options = new ConnectOptions()
2217
{
23-
BrowserWSEndpoint = Browser.WebSocketEndpoint
18+
BrowserWSEndpoint = Browser.WebSocketEndpoint,
19+
Protocol = ((Browser)Browser).Protocol,
2420
};
2521
var browser = await Puppeteer.ConnectAsync(options, TestConstants.LoggerFactory);
2622
await using (var page = await browser.NewPageAsync())
@@ -55,30 +51,29 @@ await Task.WhenAll(
5551
[Test, Retry(2), PuppeteerTest("launcher.spec", "Launcher specs Puppeteer Puppeteer.connect", "should support ignoreHTTPSErrors option")]
5652
public async Task ShouldSupportIgnoreHTTPSErrorsOption()
5753
{
58-
await using (var originalBrowser = await Puppeteer.LaunchAsync(TestConstants.DefaultBrowserOptions()))
59-
await using (var browser = await Puppeteer.ConnectAsync(new ConnectOptions
54+
await using var originalBrowser = await Puppeteer.LaunchAsync(TestConstants.DefaultBrowserOptions());
55+
await using var browser = await Puppeteer.ConnectAsync(new ConnectOptions
6056
{
6157
BrowserWSEndpoint = originalBrowser.WebSocketEndpoint,
62-
IgnoreHTTPSErrors = true
63-
}))
64-
await using (var page = await browser.NewPageAsync())
65-
{
66-
var requestTask = HttpsServer.WaitForRequest(
67-
"/empty.html",
68-
request => request?.HttpContext?.Features?.Get<ITlsHandshakeFeature>()?.Protocol);
69-
var responseTask = page.GoToAsync(TestConstants.HttpsPrefix + "/empty.html");
70-
71-
await Task.WhenAll(
72-
requestTask,
73-
responseTask).WithTimeout(Puppeteer.DefaultTimeout);
74-
75-
var response = responseTask.Result;
76-
Assert.True(response.Ok);
77-
Assert.NotNull(response.SecurityDetails);
78-
Assert.AreEqual(
79-
TestUtils.CurateProtocol(requestTask.Result.ToString()),
80-
TestUtils.CurateProtocol(response.SecurityDetails.Protocol));
81-
}
58+
IgnoreHTTPSErrors = true,
59+
Protocol = ((Browser)Browser).Protocol,
60+
});
61+
await using var page = await browser.NewPageAsync();
62+
var requestTask = HttpsServer.WaitForRequest(
63+
"/empty.html",
64+
request => request?.HttpContext.Features.Get<ITlsHandshakeFeature>()?.Protocol);
65+
var responseTask = page.GoToAsync(TestConstants.HttpsPrefix + "/empty.html");
66+
67+
await Task.WhenAll(
68+
requestTask,
69+
responseTask).WithTimeout(Puppeteer.DefaultTimeout);
70+
71+
var response = responseTask.Result;
72+
Assert.True(response.Ok);
73+
Assert.NotNull(response.SecurityDetails);
74+
Assert.AreEqual(
75+
TestUtils.CurateProtocol(requestTask.Result.ToString()),
76+
TestUtils.CurateProtocol(response.SecurityDetails.Protocol));
8277
}
8378

8479
[Test, Retry(2), PuppeteerTest("launcher.spec", "Launcher specs Puppeteer Puppeteer.connect", "should support targetFilter option")]
@@ -94,7 +89,8 @@ public async Task ShouldSupportTargetFilter()
9489
var remoteBrowser = await Puppeteer.ConnectAsync(new ConnectOptions
9590
{
9691
BrowserWSEndpoint = browser.WebSocketEndpoint,
97-
TargetFilter = (Target target) => !target.Url.Contains("should-be-ignored"),
92+
TargetFilter = target => !target.Url.Contains("should-be-ignored"),
93+
Protocol = ((Browser)browser).Protocol,
9894
}, TestConstants.LoggerFactory);
9995

10096
var pages = await remoteBrowser.PagesAsync();
@@ -105,7 +101,7 @@ public async Task ShouldSupportTargetFilter()
105101
"about:blank",
106102
TestConstants.EmptyPage
107103
},
108-
pages.Select((IPage p) => p.Url).OrderBy(t => t));
104+
pages.Select(p => p.Url).OrderBy(t => t));
109105

110106
await page2.CloseAsync();
111107
await page1.CloseAsync();
@@ -136,7 +132,8 @@ public async Task ShouldBeAbleToReconnectToADisconnectedBrowser()
136132
{
137133
var options = new ConnectOptions()
138134
{
139-
BrowserWSEndpoint = Browser.WebSocketEndpoint
135+
BrowserWSEndpoint = Browser.WebSocketEndpoint,
136+
Protocol = ((Browser)Browser).Protocol,
140137
};
141138

142139
var url = TestConstants.ServerUrl + "/frames/nested-frames.html";
@@ -161,7 +158,8 @@ public async Task ShouldBeAbleToConnectToTheSamePageSimultaneously()
161158
var browserOne = await Puppeteer.LaunchAsync(new LaunchOptions());
162159
var browserTwo = await Puppeteer.ConnectAsync(new ConnectOptions
163160
{
164-
BrowserWSEndpoint = browserOne.WebSocketEndpoint
161+
BrowserWSEndpoint = browserOne.WebSocketEndpoint,
162+
Protocol = ((Browser)browserOne).Protocol,
165163
});
166164
var tcs = new TaskCompletionSource<IPage>();
167165
async void TargetCreated(object sender, TargetChangedArgs e)
@@ -192,7 +190,8 @@ public async Task ShouldBeAbleToReconnect()
192190

193191
var browserTwo = await Puppeteer.ConnectAsync(new ConnectOptions
194192
{
195-
BrowserWSEndpoint = browserWSEndpoint
193+
BrowserWSEndpoint = browserWSEndpoint,
194+
Protocol = ((Browser)browserOne).Protocol,
196195
});
197196

198197
var pages = await browserTwo.PagesAsync();

lib/PuppeteerSharp.Tests/TestConstants.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ public static class TestConstants
4848
EnqueueAsyncMessages = Convert.ToBoolean(Environment.GetEnvironmentVariable("ENQUEUE_ASYNC_MESSAGES") ?? "false"),
4949
Timeout = 0,
5050
LogProcess = true,
51+
Protocol = PuppeteerTestAttribute.IsCdp ? ProtocolType.Cdp : ProtocolType.WebdriverBiDi,
5152
#if NETCOREAPP
5253
EnqueueTransportMessages = false
5354
#else
@@ -58,6 +59,7 @@ public static class TestConstants
5859
public static LaunchOptions BrowserWithExtensionOptions() => new()
5960
{
6061
Headless = false,
62+
Protocol = PuppeteerTestAttribute.IsCdp ? ProtocolType.Cdp : ProtocolType.WebdriverBiDi,
6163
Args = new[]
6264
{
6365
$"--disable-extensions-except={ExtensionPath.Quote()}",

0 commit comments

Comments
 (0)