GithubHelp home page GithubHelp logo

osiris-team / hbrowser Goto Github PK

View Code? Open in Web Editor NEW
114.0 5.0 8.0 329 KB

Headless/full Java browser with support for downloading files, working with cookies, retrieving HTML and simulating real user input. Possible via Node.js with Puppeteer and/or Playwright. Main focus on ease of use and high-level methods.

License: MIT License

Java 85.22% HTML 14.78%
java headless browser jsoup html javascript puppeteer nodejs playwright gson

hbrowser's Introduction

HBrowser

Headless/full Java browser with support for downloading files, working with cookies, retrieving HTML and simulating real user input. Possible via Node.js with Puppeteer and/or Playwright. Main focus on ease of use and high-level methods. Add this to your project with Maven/Gradle/Sbt/Leinigen (Java 8 or higher required).

try(PlaywrightWindow window = HB.newWin()){
    window.load("https://example.com");
   // ...   
}

All examples here. Note that the first run may take a bit because Node.js and its modules get installed into your current working dir under ./headless-browser.

Features

  • High-Level methods for...
    • downloading files.
    • working with cookies.
    • retrieving HTML.
    • simulating real user input.
  • Integrated evasions for headless detection: HB.newWinBuilder().headless(true).makeUndetectable(true)...
  • Easy access to Node.js from within Java: new NodeContext().executeJavaScript("console.log('Hello!');");
  • HTML handling via Jsoup and JSON with Gson.

How good are the evasions?

image

try (PlaywrightWindow w = HB.newWinBuilder()
     .headless(true).makeUndetectable(true).buildPlaywrightWindow())
{
    w.load("https://infosimples.github.io/detect-headless/");
    w.makeScreenshot(new File("screenshot.png"), true);
} 
catch (Exception e) {e.printStackTrace();}

Last checked 18.06.2024.

Drivers

Playwright is the default and recommended browser driver to use, since it supports downloads and more of its features were ported to Java. Checkout JG-Browser for a browser completely written in Java.

Name JS-Engine Downloads
Playwright Node.js/V8 Yes
Puppeteer Node.js/V8 No

You can find their versions in this class, which also allows you to set custom versions. (JS = JavaScript; Downloads = If the browser is able to download files other than html/xml/pdf;)

Contribute/Build

Beginners

If you have never contributed before, we recommend this Beginners Article. If you are planning to make big changes, create an issue first, where you explain what you want to do. Thank you in advance for every contribution! If you don't know how to import a GitHub project, check out this guide: IntelliJ IDEA Cloning Guide

Build-Details

Libraries

Name/Link Usage License
Playwright Emulates different types of browsers License
Puppeteer Emulates different types of browsers License
Node.js Enables executing JavaScript code License
Jsoup Used to load pages and modify their HTML code License

hbrowser's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

hbrowser's Issues

Fix error on NodeWindow close

Executing following JS-Code: await browser.close();
Writing line to NodeJS context: .load D:\Coding\JAVA\Headless-Browser\NodeJS-Installation\node-v16.10.0-win-x64\temp-1040366024.js
[Node-JS-ERROR] Error: glob dependency not found, set `options.disableGlob = true` if intentional
[Node-JS-ERROR]     at defaults (D:\Coding\JAVA\Headless-Browser\node_modules\rimraf\rimraf.js:42:11)
[Node-JS-ERROR]     at rimraf (D:\Coding\JAVA\Headless-Browser\node_modules\rimraf\rimraf.js:60:3)
[Node-JS-ERROR]     at node:internal/util:363:7
[Node-JS-ERROR]     at new Promise (<anonymous>)
[Node-JS-ERROR]     at rimraf (node:internal/util:349:12)
[Node-JS-ERROR]     at ChildProcess.<anonymous> (D:\Coding\JAVA\Headless-Browser\node_modules\puppeteer\lib\cjs\puppeteer\node\BrowserRunner.js:99:21)
[Node-JS-ERROR]     at Object.onceWrapper (node:events:510:26)
[com.osiris.headlessbrowser.NodeContext@61cc61f9] > > > > > > > Uncaught:
[Node-JS-ERROR]     at ChildProcess.emit (node:events:390:28)
[Node-JS-ERROR]     at ChildProcess.emit (node:domain:537:15)
[Node-JS-ERROR]     at Process.ChildProcess._handle.onexit (node:internal/child_process:290:12)
[com.osiris.headlessbrowser.NodeContext@61cc61f9] Error: glob dependency not found, set `options.disableGlob = true` if intentional
[com.osiris.headlessbrowser.NodeContext@61cc61f9]     at defaults (D:\Coding\JAVA\Headless-Browser\node_modules\rimraf\rimraf.js:42:11)
[com.osiris.headlessbrowser.NodeContext@61cc61f9]     at rimraf (D:\Coding\JAVA\Headless-Browser\node_modules\rimraf\rimraf.js:60:3)
[com.osiris.headlessbrowser.NodeContext@61cc61f9]     at node:internal/util:363:7
[com.osiris.headlessbrowser.NodeContext@61cc61f9]     at new Promise (<anonymous>)
[com.osiris.headlessbrowser.NodeContext@61cc61f9]     at rimraf (node:internal/util:349:12)
[com.osiris.headlessbrowser.NodeContext@61cc61f9]     at ChildProcess.<anonymous> (D:\Coding\JAVA\Headless-Browser\node_modules\puppeteer\lib\cjs\puppeteer\node\BrowserRunner.js:99:21)
[com.osiris.headlessbrowser.NodeContext@61cc61f9]     at Object.onceWrapper (node:events:510:26)
[com.osiris.headlessbrowser.NodeContext@61cc61f9]     at ChildProcess.emit (node:events:390:28)
[com.osiris.headlessbrowser.NodeContext@61cc61f9]     at ChildProcess.emit (node:domain:537:15)
[com.osiris.headlessbrowser.NodeContext@61cc61f9]     at Process.ChildProcess._handle.onexit (node:internal/child_process:290:12)
[com.osiris.headlessbrowser.NodeContext@61cc61f9] > 

Process finished with exit code 0

Cause: java.io.IOException: Stream closed (in NodeContext)

[29-03-2022 09:11:58][SPPU][WARN] Cause-Stacktrace:
[29-03-2022 09:11:58][SPPU][WARN] com.osiris.headlessbrowser.js.contexts.NodeContext.executeJavaScript(NodeContext.java:398)
[29-03-2022 09:11:58][SPPU][WARN] com.osiris.headlessbrowser.js.contexts.NodeContext.executeJavaScript(NodeContext.java:304)
[29-03-2022 09:11:58][SPPU][WARN] com.osiris.headlessbrowser.js.contexts.NodeContext.(NodeContext.java:195)
[29-03-2022 09:11:58][SPPU][WARN] com.osiris.headlessbrowser.windows.PlaywrightWindow.(PlaywrightWindow.java:57)
[29-03-2022 09:11:58][SPPU][WARN] com.osiris.headlessbrowser.windows.WindowBuilder.buildPlaywrightWindow(WindowBuilder.java:75)
[29-03-2022 09:11:58][SPPU][WARN] com.osiris.SPPU.plugins.TaskPluginsUpdater.runAtStart(TaskPluginsUpdater.java:285)
[29-03-2022 09:11:58][SPPU][WARN] com.osiris.betterthread.BetterThread.run(BetterThread.java:153)

Click with promise.All

I'm testing site navigation with Playwright codegen mode (https://playwright.dev/docs/codegen) and I note that some click produce something like:

await Promise.all([
   page.click('text=Confirm'),
   page.waitForNavigation(),
]);

I have a spefic page where this is importat because of some async RestAPI calls.
How could be handle it with HBrowser?

Fix NodeJs issues

Initialising NodeJS... SUCCESS!
Node-JS was started from: C:\Coding\Java\Headless-Browser\NodeJS-Installation\node-v16.10.0-win-x64\node.exe
Writing line to NodeJS context: const executeJavaScriptAndGetResult = null;
[NPM-INSTALL] Installing 'puppeteer'...
[Node-JS] Welcome to Node.js v16.10.0.
[Node-JS] Type ".help" for more information.
[Node-JS] > > > undefined
[NPM] 
[NPM] up to date, audited 95 packages in 2s
[NPM] 
[NPM] 9 packages are looking for funding
[NPM]   run `npm fund` for details
[NPM] 
[NPM] found 0 vulnerabilities
[NPM-INSTALL] Installed 'puppeteer' successfully!
START ===>
// Writing line(s) to NodeJS context:
const puppeteer = require('puppeteer');const browser = await puppeteer.launch();
const page = await browser.newPage();

END <===
Writing line to NodeJS context: await page.goto('https://example.com');
START ===>
// Writing line(s) to NodeJS context:
executeJavaScriptAndGetResult = function() {
var result = await page.evaluate(() => document.body.innerHTML);
var fs = require('fs')
fs.writeFile('C:\Coding\Java\Headless-Browser\NodeJS-Installation\node-v16.10.0-win-x64\executeJavaScriptAndGetResult.txt', result, err => {
  if (err) {
    console.error(err)
    return
  }
  //file written successfully
})
};executeJavaScriptAndGetResult();executeJavaScriptAndGetResult = null;
END <===
<html>
 <head></head>
 <body></body>
</html>
[Node-JS] > > > > > > Uncaught TypeError: Cannot read properties of undefined (reading 'newPage')
[Node-JS]     at REPL5:1:53
[Node-JS] > > > > > > ... ... ... ..... ....... ....... ....... ..... ..... ... Uncaught SyntaxError: 
[Node-JS] var result = await page.evaluate(() => document.body.innerHTML);
[Node-JS]                    ^
[Node-JS] 
[Node-JS] Unexpected token 'p'
[Node-JS] > > Uncaught TypeError: Cannot read properties of undefined (reading 'goto')
[Node-JS]     at REPL8:1:35
[Node-JS] > undefined

java.lang.RuntimeException: java.lang.Exception: node.exe couldn't be found in

import com.osiris.headlessbrowser.HBrowser;
import com.osiris.headlessbrowser.windows.PlaywrightWindow;

public class Main {
public static void main(String[] args) {
HBrowser hBrowser = new HBrowser();
try (PlaywrightWindow window = hBrowser.openWindow()) {
window.load("https://example.com");
System.out.println(window.getInnerHtml());
} catch (Exception e) {
e.printStackTrace();
}
}
}

Error during installation of NodeJS. Details:
java.lang.RuntimeException: java.lang.RuntimeException: java.lang.Exception: node.exe couldn't be found in D:\Projects\WebDriverPleaseWork\headless-browser\node-js\download.zip
at com.osiris.headlessbrowser.windows.PlaywrightWindow.(PlaywrightWindow.java:192)
at com.osiris.headlessbrowser.windows.WindowBuilder.buildPlaywrightWindow(WindowBuilder.java:79)
at com.osiris.headlessbrowser.HBrowser.openWindow(HBrowser.java:30)
at Main.main(Main.java:7)
Caused by: java.lang.RuntimeException: java.lang.Exception: node.exe couldn't be found in D:\Projects\WebDriverPleaseWork\headless-browser\node-js\download.zip
at com.osiris.headlessbrowser.js.contexts.NodeContext.(NodeContext.java:151)
at com.osiris.headlessbrowser.windows.PlaywrightWindow.(PlaywrightWindow.java:58)
... 3 more
Caused by: java.lang.Exception: node.exe couldn't be found in D:\Projects\WebDriverPleaseWork\headless-browser\node-js\download.zip
at com.osiris.headlessbrowser.js.contexts.NodeContext.(NodeContext.java:144)
... 4 more

Process finished with exit code 0

Fail to download NodeJs on Mac ARM

The URL to get Node JS on MacOS ARM seem to be wrong. The aarch64 (arm64) is detected correctly but the library does not find https://nodejs.org/dist/v22.3.0/node-v22.3.0-darwin-arm64.tar.gz

Caused by: java.lang.RuntimeException: java.io.FileNotFoundException: Failed to find latest NodeJS download url at 'https://nodejs.org/dist/v22.3.0/' for OS 'mac' with ARCH 'AARCH64'.
	at com.osiris.headlessbrowser.js.contexts.NodeContext.<init>(NodeContext.java:158)
	at com.osiris.headlessbrowser.windows.PlaywrightWindow.<init>(PlaywrightWindow.java:57)
	at com.osiris.headlessbrowser.windows.WindowBuilder.buildPlaywrightWindow(WindowBuilder.java:88)
	at com.osiris.headlessbrowser.HB.newWin(HB.java:17)
	at Build_gradle$1$1.execute(build.gradle.kts:9)
	at Build_gradle$1$1.execute(build.gradle.kts:8)
	at org.gradle.api.internal.AbstractTask$TaskActionWrapper.execute(AbstractTask.java:831)
	at org.gradle.api.internal.AbstractTask$TaskActionWrapper.execute(AbstractTask.java:804)
	at org.gradle.api.internal.tasks.execution.TaskExecution$3.run(TaskExecution.java:244)
	at org.gradle.internal.operations.DefaultBuildOperationRunner$1.execute(DefaultBuildOperationRunner.java:29)
	at org.gradle.internal.operations.DefaultBuildOperationRunner$1.execute(DefaultBuildOperationRunner.java:26)
	at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:66)
	at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:59)
	at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:166)
	at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:59)
	at org.gradle.internal.operations.DefaultBuildOperationRunner.run(DefaultBuildOperationRunner.java:47)
	at org.gradle.api.internal.tasks.execution.TaskExecution.executeAction(TaskExecution.java:229)
	at org.gradle.api.internal.tasks.execution.TaskExecution.executeActions(TaskExecution.java:212)
	at org.gradle.api.internal.tasks.execution.TaskExecution.executeWithPreviousOutputFiles(TaskExecution.java:195)
	at org.gradle.api.internal.tasks.execution.TaskExecution.execute(TaskExecution.java:162)
	at org.gradle.internal.execution.steps.ExecuteStep.executeInternal(ExecuteStep.java:105)
	at org.gradle.internal.execution.steps.ExecuteStep.access$000(ExecuteStep.java:44)
	at org.gradle.internal.execution.steps.ExecuteStep$1.call(ExecuteStep.java:59)
	at org.gradle.internal.execution.steps.ExecuteStep$1.call(ExecuteStep.java:56)
	at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:209)
	at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:204)
	at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:66)
	at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:59)
	at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:166)
	at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:59)
	at org.gradle.internal.operations.DefaultBuildOperationRunner.call(DefaultBuildOperationRunner.java:53)
	at org.gradle.internal.execution.steps.ExecuteStep.execute(ExecuteStep.java:56)
	at org.gradle.internal.execution.steps.ExecuteStep.execute(ExecuteStep.java:44)
	at org.gradle.internal.execution.steps.CancelExecutionStep.execute(CancelExecutionStep.java:41)
	at org.gradle.internal.execution.steps.TimeoutStep.executeWithoutTimeout(TimeoutStep.java:74)
	at org.gradle.internal.execution.steps.TimeoutStep.execute(TimeoutStep.java:55)
	at org.gradle.internal.execution.steps.PreCreateOutputParentsStep.execute(PreCreateOutputParentsStep.java:50)
	at org.gradle.internal.execution.steps.PreCreateOutputParentsStep.execute(PreCreateOutputParentsStep.java:28)
	at org.gradle.internal.execution.steps.RemovePreviousOutputsStep.execute(RemovePreviousOutputsStep.java:67)
	at org.gradle.internal.execution.steps.RemovePreviousOutputsStep.execute(RemovePreviousOutputsStep.java:37)
	at org.gradle.internal.execution.steps.BroadcastChangingOutputsStep.execute(BroadcastChangingOutputsStep.java:61)
	at org.gradle.internal.execution.steps.BroadcastChangingOutputsStep.execute(BroadcastChangingOutputsStep.java:26)
	at org.gradle.internal.execution.steps.CaptureOutputsAfterExecutionStep.execute(CaptureOutputsAfterExecutionStep.java:67)
	at org.gradle.internal.execution.steps.CaptureOutputsAfterExecutionStep.execute(CaptureOutputsAfterExecutionStep.java:45)
	at org.gradle.internal.execution.steps.ResolveInputChangesStep.execute(ResolveInputChangesStep.java:40)
	at org.gradle.internal.execution.steps.ResolveInputChangesStep.execute(ResolveInputChangesStep.java:29)
	at org.gradle.internal.execution.steps.BuildCacheStep.executeWithoutCache(BuildCacheStep.java:189)
	at org.gradle.internal.execution.steps.BuildCacheStep.lambda$execute$1(BuildCacheStep.java:75)
	at org.gradle.internal.Either$Right.fold(Either.java:175)
	at org.gradle.internal.execution.caching.CachingState.fold(CachingState.java:62)
	at org.gradle.internal.execution.steps.BuildCacheStep.execute(BuildCacheStep.java:73)
	at org.gradle.internal.execution.steps.BuildCacheStep.execute(BuildCacheStep.java:48)
	at org.gradle.internal.execution.steps.StoreExecutionStateStep.execute(StoreExecutionStateStep.java:46)
	at org.gradle.internal.execution.steps.StoreExecutionStateStep.execute(StoreExecutionStateStep.java:35)
	at org.gradle.internal.execution.steps.SkipUpToDateStep.executeBecause(SkipUpToDateStep.java:76)
	at org.gradle.internal.execution.steps.SkipUpToDateStep.lambda$execute$2(SkipUpToDateStep.java:54)
	at org.gradle.internal.execution.steps.SkipUpToDateStep.execute(SkipUpToDateStep.java:54)
	at org.gradle.internal.execution.steps.SkipUpToDateStep.execute(SkipUpToDateStep.java:36)
	at org.gradle.internal.execution.steps.legacy.MarkSnapshottingInputsFinishedStep.execute(MarkSnapshottingInputsFinishedStep.java:37)
	at org.gradle.internal.execution.steps.legacy.MarkSnapshottingInputsFinishedStep.execute(MarkSnapshottingInputsFinishedStep.java:27)
	at org.gradle.internal.execution.steps.ResolveIncrementalCachingStateStep.executeDelegate(ResolveIncrementalCachingStateStep.java:49)
	at org.gradle.internal.execution.steps.ResolveIncrementalCachingStateStep.executeDelegate(ResolveIncrementalCachingStateStep.java:27)
	at org.gradle.internal.execution.steps.AbstractResolveCachingStateStep.execute(AbstractResolveCachingStateStep.java:71)
	at org.gradle.internal.execution.steps.AbstractResolveCachingStateStep.execute(AbstractResolveCachingStateStep.java:39)
	at org.gradle.internal.execution.steps.ResolveChangesStep.execute(ResolveChangesStep.java:65)
	at org.gradle.internal.execution.steps.ResolveChangesStep.execute(ResolveChangesStep.java:36)
	at org.gradle.internal.execution.steps.ValidateStep.execute(ValidateStep.java:106)
	at org.gradle.internal.execution.steps.ValidateStep.execute(ValidateStep.java:55)
	at org.gradle.internal.execution.steps.AbstractCaptureStateBeforeExecutionStep.execute(AbstractCaptureStateBeforeExecutionStep.java:64)
	at org.gradle.internal.execution.steps.AbstractCaptureStateBeforeExecutionStep.execute(AbstractCaptureStateBeforeExecutionStep.java:43)
	at org.gradle.internal.execution.steps.AbstractSkipEmptyWorkStep.executeWithNonEmptySources(AbstractSkipEmptyWorkStep.java:125)
	at org.gradle.internal.execution.steps.AbstractSkipEmptyWorkStep.execute(AbstractSkipEmptyWorkStep.java:56)
	at org.gradle.internal.execution.steps.AbstractSkipEmptyWorkStep.execute(AbstractSkipEmptyWorkStep.java:36)
	at org.gradle.internal.execution.steps.legacy.MarkSnapshottingInputsStartedStep.execute(MarkSnapshottingInputsStartedStep.java:38)
	at org.gradle.internal.execution.steps.LoadPreviousExecutionStateStep.execute(LoadPreviousExecutionStateStep.java:36)
	at org.gradle.internal.execution.steps.LoadPreviousExecutionStateStep.execute(LoadPreviousExecutionStateStep.java:23)
	at org.gradle.internal.execution.steps.HandleStaleOutputsStep.execute(HandleStaleOutputsStep.java:75)
	at org.gradle.internal.execution.steps.HandleStaleOutputsStep.execute(HandleStaleOutputsStep.java:41)
	at org.gradle.internal.execution.steps.AssignMutableWorkspaceStep.lambda$execute$0(AssignMutableWorkspaceStep.java:35)
	at org.gradle.api.internal.tasks.execution.TaskExecution$4.withWorkspace(TaskExecution.java:289)
	at org.gradle.internal.execution.steps.AssignMutableWorkspaceStep.execute(AssignMutableWorkspaceStep.java:31)
	at org.gradle.internal.execution.steps.AssignMutableWorkspaceStep.execute(AssignMutableWorkspaceStep.java:22)
	at org.gradle.internal.execution.steps.ChoosePipelineStep.execute(ChoosePipelineStep.java:40)
	at org.gradle.internal.execution.steps.ChoosePipelineStep.execute(ChoosePipelineStep.java:23)
	at org.gradle.internal.execution.steps.ExecuteWorkBuildOperationFiringStep.lambda$execute$2(ExecuteWorkBuildOperationFiringStep.java:67)
	at org.gradle.internal.execution.steps.ExecuteWorkBuildOperationFiringStep.execute(ExecuteWorkBuildOperationFiringStep.java:67)
	at org.gradle.internal.execution.steps.ExecuteWorkBuildOperationFiringStep.execute(ExecuteWorkBuildOperationFiringStep.java:39)
	at org.gradle.internal.execution.steps.IdentityCacheStep.execute(IdentityCacheStep.java:46)
	at org.gradle.internal.execution.steps.IdentityCacheStep.execute(IdentityCacheStep.java:34)
	at org.gradle.internal.execution.steps.IdentifyStep.execute(IdentifyStep.java:48)
	at org.gradle.internal.execution.steps.IdentifyStep.execute(IdentifyStep.java:35)
	at org.gradle.internal.execution.impl.DefaultExecutionEngine$1.execute(DefaultExecutionEngine.java:61)
	at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeIfValid(ExecuteActionsTaskExecuter.java:127)
	at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.execute(ExecuteActionsTaskExecuter.java:116)
	at org.gradle.api.internal.tasks.execution.FinalizePropertiesTaskExecuter.execute(FinalizePropertiesTaskExecuter.java:46)
	at org.gradle.api.internal.tasks.execution.ResolveTaskExecutionModeExecuter.execute(ResolveTaskExecutionModeExecuter.java:51)
	at org.gradle.api.internal.tasks.execution.SkipTaskWithNoActionsExecuter.execute(SkipTaskWithNoActionsExecuter.java:57)
	at org.gradle.api.internal.tasks.execution.SkipOnlyIfTaskExecuter.execute(SkipOnlyIfTaskExecuter.java:74)
	at org.gradle.api.internal.tasks.execution.CatchExceptionTaskExecuter.execute(CatchExceptionTaskExecuter.java:36)
	at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter$1.executeTask(EventFiringTaskExecuter.java:77)
	at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter$1.call(EventFiringTaskExecuter.java:55)
	at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter$1.call(EventFiringTaskExecuter.java:52)
	at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:209)
	at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:204)
	at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:66)
	at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:59)
	at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:166)
	at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:59)
	at org.gradle.internal.operations.DefaultBuildOperationRunner.call(DefaultBuildOperationRunner.java:53)
	at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter.execute(EventFiringTaskExecuter.java:52)
	at org.gradle.execution.plan.LocalTaskNodeExecutor.execute(LocalTaskNodeExecutor.java:42)
	at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$InvokeNodeExecutorsAction.execute(DefaultTaskExecutionGraph.java:331)
	at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$InvokeNodeExecutorsAction.execute(DefaultTaskExecutionGraph.java:318)
	at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$BuildOperationAwareExecutionAction.lambda$execute$0(DefaultTaskExecutionGraph.java:314)
	at org.gradle.internal.operations.CurrentBuildOperationRef.with(CurrentBuildOperationRef.java:80)
	at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$BuildOperationAwareExecutionAction.execute(DefaultTaskExecutionGraph.java:314)
	at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$BuildOperationAwareExecutionAction.execute(DefaultTaskExecutionGraph.java:303)
	at org.gradle.execution.plan.DefaultPlanExecutor$ExecutorWorker.execute(DefaultPlanExecutor.java:463)
	at org.gradle.execution.plan.DefaultPlanExecutor$ExecutorWorker.run(DefaultPlanExecutor.java:380)
	at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:64)
	at org.gradle.internal.concurrent.AbstractManagedExecutor$1.run(AbstractManagedExecutor.java:47)
Caused by: java.io.FileNotFoundException: Failed to find latest NodeJS download url at 'https://nodejs.org/dist/v22.3.0/' for OS 'mac' with ARCH 'AARCH64'.
	at com.osiris.headlessbrowser.js.contexts.NodeContext.install(NodeContext.java:273)
	at com.osiris.headlessbrowser.js.contexts.NodeContext.<init>(NodeContext.java:131)
	... 120 more

Wrong NodeJS architecture in installation (Windows x64/amd64)

Running a test code in a Windows x64/amd64 pc, HBrowser install NodeJS from node-v20.7.0-win-arm64.zip and then when the task starts, fails with:

Exception in thread "main" java.lang.RuntimeException: java.io.IOException:
Cannot run program "C:\temp\Cgil\HBrowser\headless-browser\node-js\node-js-installation\node-v20.7.0-win-arm64\node.exe

Two suggestions: screenshots, and table-of-features

I suggest two things:

(1) add screenshots, no matter how incomplete it is so far, ideally of some simple website, and then perhaps also at some later point a more complicated web site

(2) for attracting devs, I'd recommend a table of implemented (and missing) features. That way people can quickly look at what needs work and can invest a little bit of time perhaps when they see amount of work required for this or that feature

Just two suggestions! Please feel free to ignore this or close it at any moment in time for any reason.

java.lang.RuntimeException: java.io.IOException: Stream closed

Error during start of NodeJS! Details:

java.lang.RuntimeException: java.io.IOException: Stream closed
java.lang.RuntimeException: java.lang.RuntimeException: java.io.IOException: Stream closed
at com.osiris.headlessbrowser.js.contexts.NodeContext.(NodeContext.java:164)
at com.osiris.headlessbrowser.windows.PlaywrightWindow.(PlaywrightWindow.java:56)
at com.osiris.headlessbrowser.windows.WindowBuilder.buildPlaywrightWindow(WindowBuilder.java:81)
Caused by: java.lang.RuntimeException: java.io.IOException: Stream closed
at com.osiris.headlessbrowser.js.contexts.NodeContext.executeJavaScript(NodeContext.java:436)
at com.osiris.headlessbrowser.js.contexts.NodeContext.executeJavaScript(NodeContext.java:342)
at com.osiris.headlessbrowser.js.contexts.NodeContext.(NodeContext.java:149)
... 87 more
Caused by: java.io.IOException: Stream closed
at java.base/java.lang.ProcessBuilder$NullOutputStream.write(ProcessBuilder.java:442)
at java.base/java.io.OutputStream.write(OutputStream.java:157)
at java.base/java.io.BufferedOutputStream.flushBuffer(BufferedOutputStream.java:81)
at java.base/java.io.BufferedOutputStream.flush(BufferedOutputStream.java:142)
at com.osiris.headlessbrowser.js.contexts.NodeContext.writeLine(NodeContext.java:327)
at com.osiris.headlessbrowser.js.contexts.NodeContext.executeJavaScriptFromFile(NodeContext.java:512)
at com.osiris.headlessbrowser.js.contexts.NodeContext.executeJavaScript(NodeContext.java:401)
... 89 more

Growing node.exe memory

Hi, in Windows machine I'm testing a loop with 2 load method with Playwright browser and I note that the process node.exe still grow without ever release.
Is it correct? Is there some trick to release it?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.