Skip to content

Commit

Permalink
[BREAKING] Introduce new headless mode (#2492)
Browse files Browse the repository at this point in the history
* Introduce new headless mode

* Add reference

* Change workflow title

* fix actions

* fix test

* fix a test

* fix formatting

* Fix auth tests

* Fix a webworker test

* Fix requestFinished

* fix should be able to fetch dataURL and fire dataURL requests

* dotnet format

* Undo debugging thing

* Improve test

* Fix more tests

* Fix CloseAsync race

* fix build

* change a test name

* Fix response from cache test.

* oops

* Some fixes

* fix test

* Ignore a flaky test
  • Loading branch information
kblok committed Mar 12, 2024
1 parent da30a58 commit b87a9d7
Show file tree
Hide file tree
Showing 26 changed files with 355 additions and 247 deletions.
40 changes: 37 additions & 3 deletions .github/workflows/dotnet.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,45 @@ env:

jobs:
build:
name: build-${{ matrix.browser }}/${{ matrix.os }}
name: build-${{ matrix.browser }}-${{ matrix.mode }}-${{ matrix.os }}
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, windows-latest]
browser: [FIREFOX,CHROME]
browser: [CHROME, FIREFOX]
mode: [headless, headful, headless-shell]
include:
- os: ubuntu-latest
browser: CHROME
mode: headless
- os: ubuntu-latest
browser: CHROME
mode: headful
- os: ubuntu-latest
browser: CHROME
mode: headless-shell
- os: ubuntu-latest
browser: FIREFOX
mode: headless
- os: ubuntu-latest
browser: FIREFOX
mode: headful
- os: windows-latest
browser: CHROME
mode: headless
- os: windows-latest
browser: CHROME
mode: headful
- os: windows-latest
browser: CHROME
mode: headless-shell
- os: windows-latest
browser: FIREFOX
mode: headless
- os: windows-latest
browser: FIREFOX
mode: headful
steps:
- uses: actions/checkout@v3
- name: Setup .NET Core
Expand Down Expand Up @@ -54,7 +86,7 @@ jobs:
New-SelfSignedCertificate -Subject "localhost" -FriendlyName "Puppeteer" -CertStoreLocation "cert:\CurrentUser\My"
Get-ChildItem -Path cert:\CurrentUSer\my | where { $_.friendlyname -eq "Puppeteer" } | Export-Certificate -FilePath $env:GITHUB_WORKSPACE\lib\PuppeteerSharp.TestServer\testCert.cer
- name: Check formatting
if: ${{ matrix.os == 'ubuntu-latest' && matrix.browser == 'CHROME' }}
if: ${{ matrix.os == 'ubuntu-latest' && matrix.browser == 'CHROME' && matrix.mode == 'headless' }}
run: dotnet format ./lib/PuppeteerSharp.sln --verify-no-changes
- name: Build
working-directory: lib
Expand All @@ -63,6 +95,7 @@ jobs:
if: matrix.os == 'ubuntu-latest'
env:
PRODUCT: ${{ matrix.browser }}
HEADLESS_MODE: ${{ matrix.mode }}
run: |
Xvfb :1 -screen 5 1024x768x8 &
export DISPLAY=:1.5
Expand All @@ -72,6 +105,7 @@ jobs:
if: matrix.os == 'windows-latest'
env:
PRODUCT: ${{ matrix.browser }}
HEADLESS_MODE: ${{ matrix.mode }}
run: |
cd .\lib\PuppeteerSharp.Tests
dotnet test -s test.runsettings --blame-hang-timeout 300000
Expand Down
3 changes: 3 additions & 0 deletions lib/PuppeteerSharp.Nunit/PuppeteerSharp.Nunit.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,8 @@
<EmbeddedResource Include="TestExpectations\TestExpectations.local.json" />
<EmbeddedResource Include="TestExpectations\TestExpectations.upstream.json" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\PuppeteerSharp\PuppeteerSharp.csproj" />
</ItemGroup>
<Import Project="../Common/CommonProps.props" />
</Project>
26 changes: 19 additions & 7 deletions lib/PuppeteerSharp.Nunit/PuppeteerTestAttribute.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,21 @@ public class PuppeteerTestAttribute : NUnitAttribute, IApplyToTest
public static readonly bool IsChrome = Environment.GetEnvironmentVariable("PRODUCT") != "FIREFOX";
// TODO: Change implementation when we implement Webdriver Bidi
public static readonly bool IsCdp = true;
public static readonly bool Headless = Convert.ToBoolean(
Environment.GetEnvironmentVariable("HEADLESS") ??
(System.Diagnostics.Debugger.IsAttached ? "false" : "true"),
System.Globalization.CultureInfo.InvariantCulture);
public static readonly HeadlessMode Headless =
string.IsNullOrEmpty(Environment.GetEnvironmentVariable("HEADLESS_MODE")) ?
(System.Diagnostics.Debugger.IsAttached ? HeadlessMode.False : HeadlessMode.True) :
GetHeadlessModeFromEnvVar(Environment.GetEnvironmentVariable("HEADLESS_MODE"));

private static HeadlessMode GetHeadlessModeFromEnvVar(string getEnvironmentVariable)
{
return getEnvironmentVariable switch
{
"headless" => HeadlessMode.True,
"headful" => HeadlessMode.False,
"headless-shell" => HeadlessMode.Shell,
_ => throw new ArgumentException("Invalid value for HEADLESS_MODE environment variable"),
};
}

/// <summary>
/// Creates a new instance of the attribute.
Expand Down Expand Up @@ -92,17 +103,18 @@ private bool ShouldSkipByExpectation(Test test, out TestExpectation output)
var currentExpectationPlatform = GetCurrentExpectationPlatform();
List<TestExpectation.TestExpectationsParameter> parameters =
[

IsChrome
? TestExpectation.TestExpectationsParameter.Chrome
: TestExpectation.TestExpectationsParameter.Firefox,

IsCdp
? TestExpectation.TestExpectationsParameter.Cdp
: TestExpectation.TestExpectationsParameter.WebDriverBiDi,
Headless
Headless.Equals(HeadlessMode.True)
? TestExpectation.TestExpectationsParameter.Headless
: TestExpectation.TestExpectationsParameter.Headful,
: Headless.Equals(HeadlessMode.False)
? TestExpectation.TestExpectationsParameter.Headful
: TestExpectation.TestExpectationsParameter.ChromeHeadlessShell
];

var localExpectations = GetLocalExpectations();
Expand Down
3 changes: 2 additions & 1 deletion lib/PuppeteerSharp.Nunit/TestExpectations/TestExpectation.cs
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,8 @@ public enum TestExpectationsParameter
Chrome,
WebDriverBiDi,
Cdp,
[EnumMember(Value = "chrome-headless-shell")] ChromeHeadlessShell,
[EnumMember(Value = "chrome-headless-shell")]
ChromeHeadlessShell,
Headless,
Headful,
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,5 +47,12 @@
"platforms": ["darwin", "linux", "win32"],
"parameters": ["firefox"],
"expectations": ["FAIL"]
},
{
"comment": "This is passing on my machine but failing on CI/CD",
"testIdPattern": "[click.spec] Page.click should fire aux event on middle click",
"platforms": ["win32"],
"parameters": ["firefox", "headful"],
"expectations": ["FAIL"]
}
]
70 changes: 35 additions & 35 deletions lib/PuppeteerSharp.TestServer/wwwroot/input/mouse-helper.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
// This injects a box into the page that moves with the mouse;
// Useful for debugging
(function () {
const box = document.createElement('div');
box.classList.add('mouse-helper');
const styleElement = document.createElement('style');
styleElement.innerHTML = `
const box = document.createElement('div');
box.classList.add('mouse-helper');
const styleElement = document.createElement('style');
styleElement.innerHTML = `
.mouse-helper {
pointer-events: none;
position: absolute;
Expand Down Expand Up @@ -40,35 +40,35 @@
border-color: rgba(0,255,0,0.9);
}
`;
document.head.appendChild(styleElement);
document.body.appendChild(box);
document.addEventListener(
'mousemove',
(event) => {
box.style.left = event.pageX + 'px';
box.style.top = event.pageY + 'px';
updateButtons(event.buttons);
},
true
);
document.addEventListener(
'mousedown',
(event) => {
updateButtons(event.buttons);
box.classList.add('button-' + event.which);
},
true
);
document.addEventListener(
'mouseup',
(event) => {
updateButtons(event.buttons);
box.classList.remove('button-' + event.which);
},
true
);
function updateButtons(buttons) {
for (let i = 0; i < 5; i++)
box.classList.toggle('button-' + i, buttons & (1 << i));
}
document.head.appendChild(styleElement);
document.body.appendChild(box);
document.addEventListener(
'mousemove',
(event) => {
box.style.left = event.pageX + 'px';
box.style.top = event.pageY + 'px';
updateButtons(event.buttons);
},
true
);
document.addEventListener(
'mousedown',
(event) => {
updateButtons(event.buttons);
box.classList.add('button-' + event.which);
},
true
);
document.addEventListener(
'mouseup',
(event) => {
updateButtons(event.buttons);
box.classList.remove('button-' + event.which);
},
true
);
function updateButtons(buttons) {
for (let i = 0; i < 5; i++)
{box.classList.toggle('button-' + i, buttons & (1 << i));}
}
})();
52 changes: 26 additions & 26 deletions lib/PuppeteerSharp.TestServer/wwwroot/input/scrollable.html
Original file line number Diff line number Diff line change
@@ -1,37 +1,37 @@
<!DOCTYPE html>
<html>
<head>
<head>
<title>Scrollable test</title>
</head>
<body>
<script src='mouse-helper.js'></script>
<script>
for (let i = 0; i < 100; i++) {
let button = document.createElement('button');
button.textContent = i + ': not clicked';
button.id = 'button-' + i;
button.onclick = () => button.textContent = 'clicked';
button.oncontextmenu = event => {
if (![2].includes(event.button)) {
</head>
<body>
<script src='mouse-helper.js'></script>
<script>
for (let i = 0; i < 100; i++) {
let button = document.createElement('button');
button.textContent = i + ': not clicked';
button.id = 'button-' + i;
button.onclick = () => button.textContent = 'clicked';
button.oncontextmenu = event => {
if (![2].includes(event.button)) {
return;
}
event.preventDefault();
button.textContent = 'context menu';
}
button.onmouseup = event => {
if (![1,3,4].includes(event.button)) {
event.preventDefault();
button.textContent = 'context menu';
}
button.onmouseup = event => {
if (![1,3,4].includes(event.button)) {
return;
}
event.preventDefault();
button.textContent = {
}
event.preventDefault();
button.textContent = {
3: 'back click',
4: 'forward click',
1: 'aux click',
}[event.button];
}
document.body.appendChild(button);
document.body.appendChild(document.createElement('br'));
}[event.button];
}
</script>
</body>
document.body.appendChild(button);
document.body.appendChild(document.createElement('br'));
}
</script>
</body>
</html>
2 changes: 1 addition & 1 deletion lib/PuppeteerSharp.TestServer/wwwroot/input/textarea.html
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<title>Textarea test</title>
</head>
<body>
<textarea></textarea>
<textarea rows="5" cols="20"></textarea>
<script src='mouse-helper.js'></script>
<script>
globalThis.result = '';
Expand Down
9 changes: 3 additions & 6 deletions lib/PuppeteerSharp.Tests/BrowserTests/BrowserVersionTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,12 @@ namespace PuppeteerSharp.Tests.BrowserTests
{
public class BrowserVersionTests : PuppeteerBrowserBaseTest
{
public BrowserVersionTests() : base()
{
}

[Test, Retry(2), PuppeteerTest("browser.spec", "Browser.version", "should return whether we are in headless")]
public async Task ShouldReturnWhetherWeAreInHeadless()
[Test, Retry(2), PuppeteerTest("browser.spec", "Browser.version", "should return version")]
public async Task ShouldReturnVersion()
{
var version = await Browser.GetVersionAsync();
Assert.IsNotEmpty(version);
StringAssert.Contains(PuppeteerTestAttribute.IsChrome ? "chrome" : "firefox", version.ToLower());
}
}
}

0 comments on commit b87a9d7

Please sign in to comment.