Skip to content

Commit

Permalink
3.0.0
Browse files Browse the repository at this point in the history
This update requires you to delete /headless-browser/node-js/node-js-installation folder
- Node installation now gets extracted to parent folder removing the need of updating the installation path after download. This also fixes issues with executing install(true) multiple times.
- Fixed newer playwright versions not installing.
  • Loading branch information
Osiris-Team committed Feb 6, 2024
1 parent 9615a32 commit d1447ed
Show file tree
Hide file tree
Showing 5 changed files with 78 additions and 12 deletions.
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

<groupId>com.osiris.headlessbrowser</groupId>
<artifactId>Headless-Browser</artifactId>
<version>2.4.3</version>
<version>3.0.0</version>
<repositories>
<repository>
<id>jitpack</id>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
package com.osiris.headlessbrowser.js.contexts;

import com.osiris.autoplug.core.UtilsFiles;
import com.osiris.betterthread.BThreadManager;
import com.osiris.headlessbrowser.exceptions.NodeJsCodeException;
import com.osiris.headlessbrowser.utils.AsyncReader;
import com.osiris.headlessbrowser.utils.DownloadTask;
import com.osiris.headlessbrowser.utils.OS;
import com.osiris.headlessbrowser.utils.TrashOutput;
import com.osiris.headlessbrowser.utils.*;
import net.lingala.zip4j.ZipFile;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.StringUtils;
Expand All @@ -18,6 +16,7 @@
import java.io.*;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.StandardCopyOption;
import java.time.Instant;
import java.util.ArrayList;
import java.util.Arrays;
Expand Down Expand Up @@ -78,9 +77,6 @@ public NodeContext(File parentNodeDir, OutputStream debugOutput, int timeout) {
try {
// Download and install NodeJS into current working directory if no installation found
install(false);
// Currently, installationDir is here --------------------> but we need this -->
// Example directory structure after install: path/node-js/node-js-installation/node-v18.6.0-win-x64
this.installationDir = new File(installationDir + "/" + installationDir.listFiles()[0].getName());

File nodeExeFile, npmExeFile, npxExeFile;
if (TYPE.equals(OS.Type.WINDOWS)) {
Expand Down Expand Up @@ -185,18 +181,20 @@ private void updatePath(ProcessBuilder processBuilder, File exeFile) {
*
* @param force if true force-installs the latest release.
*/
public void install(boolean force) throws IOException, InterruptedException {
public void install(boolean force) throws Exception {
if (!force) {
// Don't install if already done.
if (installationDir.listFiles() != null && this.installationDir.listFiles().length != 0) {
if (installationDir.listFiles() != null && installationDir.listFiles().length != 0) {
return;
}
}

FileUtils.deleteDirectory(installationDir);
close(); // If this node context is still running
if(installationDir.exists()) FileUtils.deleteDirectory(installationDir);
installationDir.mkdirs();
String url = "https://nodejs.org/dist/latest/";
debugOutput.println("Installing latest NodeJS release from '" + url + "'...");
debugOutput.println("This devices' details: "+TYPE.name+" "+ ARCH.name()+" ("+ Utils.toString(ARCH.altNames)+")");
Document docLatest = Jsoup.connect(url).get();

String downloadUrl = null;
Expand Down Expand Up @@ -249,6 +247,13 @@ public void install(boolean force) throws IOException, InterruptedException {
downloadFile.delete();
debugOutput.println(" SUCCESS!");
}

if(installationDir.listFiles().length == 1){
File f = installationDir.listFiles()[0];
if(f.isDirectory()){
Utils.moveDirectoryContent(f, f.getParentFile());
}
}
}

/**
Expand Down Expand Up @@ -292,6 +297,7 @@ private boolean containsIgnoreCase(String fileName, String[] altNames) {

@Override
public void close() throws Exception {
if(process == null) return;
debugOutput.println("CLOSING... " + this);
process.destroy();
process.waitFor();
Expand Down
39 changes: 39 additions & 0 deletions src/main/java/com/osiris/headlessbrowser/utils/Utils.java
Original file line number Diff line number Diff line change
@@ -1,15 +1,54 @@
package com.osiris.headlessbrowser.utils;

import org.apache.commons.io.FileUtils;

import java.io.*;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.nio.file.Files;
import java.nio.file.StandardCopyOption;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Objects;

public class Utils {

public static void moveDirectoryContent(File source, File target) throws IOException {
File[] files = source.listFiles();
if (files != null) {
for (File file : files) {
File destFile = new File(target, file.getName());
if (file.isDirectory()) {
moveDirectoryContent(file, destFile);
FileUtils.deleteDirectory(file); // Optionally delete the source directory after moving its content
} else {
if(!destFile.getParentFile().exists()) destFile.getParentFile().mkdirs();
Files.move(file.toPath(), destFile.toPath(), StandardCopyOption.REPLACE_EXISTING);
}
}
}
}

public static <T> String toString(T[] arr){
StringBuilder sb = new StringBuilder("[ ");
for (T t : arr) {
sb.append("'").append(t).append("' ");
}
sb.append("]");
return sb.toString();
}

public static <T> String toString(List<T> list){
StringBuilder sb = new StringBuilder("[ ");
for (T t : list) {
sb.append("'").append(t).append("' ");
}
sb.append("]");
return sb.toString();
}

/**
* Finds the wanted file inside this jar file and returns its {@link InputStream}.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,8 @@ public PlaywrightWindow(HBrowser parentBrowser, boolean enableJavaScript, Output
this.jsContext = new NodeContext(new File(userDataDir.getParentFile() + "/node-js"), debugOutput, jsTimeout);
try {
jsContext.npmInstall("playwright");
jsContext.executeNpxWithArgs("playwright", "install");
// TODO this installs all browsers (firefox and webkit), but we only need chrome

// Define global variables/constants
if (makeUndetectable) {
Expand Down Expand Up @@ -127,7 +129,10 @@ public PlaywrightWindow load(String url) throws NodeJsCodeException {
public PlaywrightWindow load(File file) throws NodeJsCodeException {
String url = "file:///" + file.getAbsolutePath().replace("\\", "/");
jsContext.executeJavaScript("" +
"response = await page.goto('" + url + "', wait_until=\"domcontentloaded\");\n");
"response = await page.goto('" + url + "', wait_until=\"networkidle\");\n");
// 06.02.2024, it seems that domcontentloaded gets not executed for files???,
// thus we do networkidle instead as the next best thing
// https://playwright.dev/docs/api/class-page#page-goto
this.url = url;
return this;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package com.osiris.headlessbrowser.js.contexts;

import org.junit.jupiter.api.Test;

import java.io.IOException;

import static org.junit.jupiter.api.Assertions.*;

class NodeContextTest {

@Test
void install() throws Exception {
NodeContext ctx = new NodeContext(null, System.out, 30); // Installs and starts Node.js if not exists
ctx.install(true);
}
}

0 comments on commit d1447ed

Please sign in to comment.