diff --git "a/docs/M\303\270tedokumenter/Internmeeting 2026.02.05.pdf" "b/docs/M\303\270tedokumenter/Internmeeting 2026.02.05.pdf"
new file mode 100644
index 0000000..e921157
Binary files /dev/null and "b/docs/M\303\270tedokumenter/Internmeeting 2026.02.05.pdf" differ
diff --git "a/docs/M\303\270tedokumenter/Internmeeting, 2026.03.19.pdf" "b/docs/M\303\270tedokumenter/Internmeeting, 2026.03.19.pdf"
new file mode 100644
index 0000000..2f01609
Binary files /dev/null and "b/docs/M\303\270tedokumenter/Internmeeting, 2026.03.19.pdf" differ
diff --git "a/docs/M\303\270tedokumenter/Retroperspektiv 1, 2026.02.12.pdf" "b/docs/M\303\270tedokumenter/Retroperspektiv 1, 2026.02.12.pdf"
new file mode 100644
index 0000000..bcb1d3d
Binary files /dev/null and "b/docs/M\303\270tedokumenter/Retroperspektiv 1, 2026.02.12.pdf" differ
diff --git "a/docs/M\303\270tedokumenter/Retroperspektiv 2, 2026.03.19.pdf" "b/docs/M\303\270tedokumenter/Retroperspektiv 2, 2026.03.19.pdf"
new file mode 100644
index 0000000..4a60910
Binary files /dev/null and "b/docs/M\303\270tedokumenter/Retroperspektiv 2, 2026.03.19.pdf" differ
diff --git "a/docs/M\303\270tedokumenter/Team meeting 2, 2026.03.17.pdf" "b/docs/M\303\270tedokumenter/Team meeting 2, 2026.03.17.pdf"
new file mode 100644
index 0000000..0990c3d
Binary files /dev/null and "b/docs/M\303\270tedokumenter/Team meeting 2, 2026.03.17.pdf" differ
diff --git "a/docs/M\303\270tedokumenter/Thursdays Meeting 2026.02.19 (With LA).pdf" "b/docs/M\303\270tedokumenter/Thursdays Meeting 2026.02.19 (With LA).pdf"
new file mode 100644
index 0000000..8f5beca
Binary files /dev/null and "b/docs/M\303\270tedokumenter/Thursdays Meeting 2026.02.19 (With LA).pdf" differ
diff --git "a/docs/M\303\270tedokumenter/Thursdays Meeting 2026.03.12 (With LA).pdf" "b/docs/M\303\270tedokumenter/Thursdays Meeting 2026.03.12 (With LA).pdf"
new file mode 100644
index 0000000..c6efc55
Binary files /dev/null and "b/docs/M\303\270tedokumenter/Thursdays Meeting 2026.03.12 (With LA).pdf" differ
diff --git a/helpmehelpapplication/pom.xml b/helpmehelpapplication/pom.xml
index 7b2f137..ec74b68 100644
--- a/helpmehelpapplication/pom.xml
+++ b/helpmehelpapplication/pom.xml
@@ -33,7 +33,7 @@
org.seleniumhq.seleniumselenium-java
- 4.41.0
+ 4.43.0com.opencsv
diff --git a/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/database/DatabaseManager.java b/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/database/DatabaseManager.java
new file mode 100644
index 0000000..6276bdf
--- /dev/null
+++ b/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/database/DatabaseManager.java
@@ -0,0 +1,384 @@
+package ntnu.systemutvikling.team6.database;
+
+import java.sql.*;
+import java.util.*;
+
+import ntnu.systemutvikling.team6.models.Charity;
+import ntnu.systemutvikling.team6.models.CharityRegistry;
+import ntnu.systemutvikling.team6.models.Donation;
+import ntnu.systemutvikling.team6.models.DonationRegistry;
+import ntnu.systemutvikling.team6.scraper.APICharityData;
+import ntnu.systemutvikling.team6.scraper.LogoDownloader;
+import ntnu.systemutvikling.team6.scraper.URLCharityScraper;
+
+/**
+ * Manages the Database with MySQL tables and JDBC.
+ *
+ *
This class is responsible for creating the tables needed for the application, if not done
+ * already and maintaining the {@code charities} table based on data retrieved from the IK API. It
+ * is also responsible for retrieving the data from the database and sending it to the application
+ * through the CharityRegistry and DonationRegistry. It is used by the FrontpageController to
+ * retrieve the data needed to display the charities
+ */
+public class DatabaseManager {
+ private final DatabaseConnection connection;
+
+ /**
+ * Contractor for DatabaseManager. It uses a DatabaseConnection object that contains a connection
+ * credentials.
+ */
+ public DatabaseManager() {
+ this.connection = new DatabaseConnection();
+ }
+
+ /**
+ * Connection test for the Database. Does a simple SELECT SQL query and returns either true og and
+ * Exception if failed
+ *
+ * @return true if Sucsedd or SQLExepction if failed
+ */
+ public boolean testConnection() {
+ try (Connection conn = connection.getMySqlConnection();
+ Statement stmt = conn.createStatement()) {
+
+ ResultSet rs = stmt.executeQuery("SELECT 1");
+
+ if (rs.next()) {
+ System.out.println("Database connection verified.");
+ return true;
+ }
+
+ } catch (SQLException e) {
+ System.out.println("Database connection failed.");
+ e.printStackTrace();
+ }
+
+ return false;
+ }
+
+ /**
+ * Creates the {@code Charities} and {@code Donations} tables if they do not already exist.
+ *
+ *
The table structure for Charities is based on fields from {@link APICharityData}.
+ *
+ * @throws RuntimeException if a {@link SQLException} occurs while creating the table
+ */
+ public void createTables() {
+ String sql_query1 =
+ """
+ -- -----------------------------------------------------
+ -- Table `HelpMeHelp`.`Charities`
+ -- -----------------------------------------------------
+ CREATE TABLE IF NOT EXISTS Charities (
+ UUID_charities CHAR(36) PRIMARY KEY,
+ org_number VARCHAR(255) NOT NULL,
+ charity_name VARCHAR(255) NOT NULL,
+ charity_link VARCHAR(255) NOT NULL,
+ pre_approved TINYINT NOT NULL,
+ status VARCHAR(255) NOT NULL,
+ description TEXT,
+ logoURL TEXT,
+ categories TEXT,
+ key_values TEXT,
+ logoBlob MEDIUMBLOB,
+ UNIQUE KEY unique_org_number (org_number)
+ ) ENGINE=InnoDB;
+
+
+ """;
+ String sql_query2 =
+ """
+ -- -----------------------------------------------------
+ -- Table `HelpMeHelp`.`Donations`
+ -- -----------------------------------------------------
+ CREATE TABLE IF NOT EXISTS Donations (
+ `UUID_Donations` CHAR(36) NOT NULL,
+ `amount` DECIMAL NOT NULL,
+ `date` DATE NOT NULL,
+ `Charities_UUID_charities` CHAR(36) NOT NULL,
+ PRIMARY KEY (`UUID_Donations`),
+ INDEX `fk_Donations_Charities_idx` (`Charities_UUID_charities` ASC) VISIBLE,
+ CONSTRAINT `fk_Donations_Charities`
+ FOREIGN KEY (`Charities_UUID_charities`)
+ REFERENCES Charities (`UUID_charities`)
+ ON DELETE CASCADE
+ ON UPDATE CASCADE)
+ ENGINE = InnoDB;
+ """;
+
+ try (Connection conn = connection.getMySqlConnection();
+ Statement s = conn.createStatement()) {
+
+ s.execute(sql_query1);
+ s.execute(sql_query2);
+ } catch (SQLException e) {
+ e.printStackTrace();
+ throw new RuntimeException("Error creating table.");
+ }
+ }
+
+ /**
+ * This method is used to verify the integrity of the data in the {@code charities} table and to
+ * update it based on the data retrieved from the IK API and the charity's URL.
+ * The param charities are retrieved from
+ * the IK API through the APICharityData class. Called in initialize method in
+ * HmHApplication.java, which is the main class of the application, to ensure that the data is up
+ * to date when the application starts. Uses a temp table to ensure that the data in the database
+ * is consistent with the data from the API.
+ *
Uses a URLScraper object to get data not contained in the API, and static methods from
+ * LogoDownloader to get the charity's logo as a blob.
+ *
+ * @param charities a list of {@code Charity} objects to add to the database
+ */
+ public void addAPIDataToTable(List charities) {
+ Connection conn = null;
+ int charityCounter = 0;
+
+ // Scrapes description, logo, categories, and key values from IK
+ for (Charity charity : charities) {
+ charityCounter++;
+
+ System.out.println("Scraping charity " + charityCounter + " of " + charities.size());
+ URLCharityScraper urlScraper = new URLCharityScraper(charity.getURL());
+ urlScraper.scrapeCharityPage();
+
+ charity.setDescription(urlScraper.getDescription());
+ charity.setCategory(urlScraper.getCategories());
+ charity.setLogoURL(urlScraper.getLogoURL());
+ charity.setKeyValues(urlScraper.getKeyValues());
+ byte[] logoBlob = LogoDownloader.downloadImageAsBlob(charity.getLogoURL());
+ charity.setLogoBlob(logoBlob);
+ }
+ try {
+ conn = connection.getMySqlConnection();
+ conn.setAutoCommit(false);
+ String sql_query =
+ """
+ INSERT INTO Charities (UUID_charities, org_number, charity_name, charity_link, pre_approved, status, description, logoURL, categories, key_values, logoBlob)
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
+ ON DUPLICATE KEY UPDATE
+ charity_name = VALUES(charity_name),
+ charity_link = VALUES(charity_link),
+ pre_approved = VALUES(pre_approved),
+ status = VALUES(status),
+ description = VALUES(description),
+ logoURL = VALUES(logoURL),
+ categories = VALUES(categories),
+ key_values = VALUES(key_values),
+ logoBlob = VALUES(logoBlob)
+ """;
+
+ try (PreparedStatement ps = conn.prepareStatement(sql_query)) {
+ for (Charity charity : charities) {
+ if (charity.getUUID() == null) {
+ ps.setString(1, UUID.randomUUID().toString());
+ } else {
+ ps.setString(1, charity.getUUID().toString());
+ }
+
+ ps.setString(2, charity.getOrg_number().replaceAll("\\s", ""));
+ ps.setString(3, charity.getName());
+ ps.setString(4, charity.getURL());
+ ps.setBoolean(5, charity.getPreApproved());
+ ps.setString(6, charity.getStatus());
+ ps.setString(7, charity.getDescription());
+ ps.setString(8, charity.getLogoURL());
+ ps.setString(9, charity.getCategory());
+ ps.setString(10, charity.getKeyValues());
+ ps.setBytes(11, charity.getLogoBlob());
+
+ ps.addBatch();
+ }
+ ps.executeBatch();
+ }
+
+ // -- Intergerty Check:
+ String createTemp =
+ """
+ CREATE TEMPORARY TABLE temp_api_charities (
+ org_number VARCHAR(20) PRIMARY KEY
+ )
+ """;
+
+ try (PreparedStatement ps = conn.prepareStatement(createTemp)) {
+ ps.execute();
+ }
+
+ String insertTemp = "INSERT IGNORE INTO temp_api_charities (org_number) VALUES (?)";
+
+ try (PreparedStatement ps = conn.prepareStatement(insertTemp)) {
+
+ for (Charity charity : charities) {
+ ps.setString(1, charity.getOrg_number().replaceAll("\\s", ""));
+ ps.addBatch();
+ }
+
+ ps.executeBatch();
+ }
+
+ String deleteSql =
+ """
+ DELETE FROM Charities c
+ WHERE NOT EXISTS (
+ SELECT 1
+ FROM temp_api_charities t
+ WHERE t.org_number = c.org_number
+ )
+ """;
+
+ try (PreparedStatement ps = conn.prepareStatement(deleteSql)) {
+ ps.executeUpdate();
+ }
+
+ conn.commit();
+
+ } catch (SQLException e) {
+ if (conn != null) {
+ try {
+ conn.rollback();
+ } catch (SQLException ex) {
+ ex.printStackTrace();
+ }
+ }
+ e.printStackTrace();
+
+ throw new RuntimeException("ERROR: Something went wrong during updating charities table.");
+ } finally {
+ if (conn != null) {
+ try {
+ conn.setAutoCommit(true);
+ conn.close();
+ } catch (SQLException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+ }
+
+ /**
+ * Fetches the data stored in the database and converts it to a list of Charity objects
+ * in the form of a registry (CharityRegistry).
+ *
+ * @return a CharityRegistry of all the charities registered in the database
+ */
+ public CharityRegistry getCharitiesFromDB() {
+ CharityRegistry registry = null;
+ Connection conn = null;
+ try {
+ conn = connection.getMySqlConnection();
+ String sql_query =
+ "SELECT UUID_charities, org_number, charity_name, charity_link, pre_approved, status, description, logoURL, " +
+ "categories, key_values, logoBlob FROM Charities";
+ Statement stmt = conn.createStatement();
+ ResultSet rs = stmt.executeQuery(sql_query);
+
+ registry = new CharityRegistry();
+ while (rs.next()) {
+ Charity charity =
+ new Charity(
+ rs.getString("UUID_charities"),
+ rs.getString("org_number"),
+ rs.getString("charity_link"),
+ rs.getString("charity_name"),
+ rs.getBoolean("pre_approved"),
+ rs.getString("status"));
+ charity.setDescription(rs.getString("description"));
+ charity.setLogoURL(rs.getString("logoURL"));
+ charity.setCategory(rs.getString("categories"));
+ charity.setKeyValues(rs.getString("key_values"));
+ charity.setLogoBlob(rs.getBytes("logoBlob"));
+
+ registry.addCharity(charity);
+ }
+ } catch (SQLException e) {
+ e.printStackTrace();
+ throw new RuntimeException("ERROR: Something went wrong during updating charities table.");
+ }
+ return registry;
+ }
+
+ public List getCategoriesFromDB() {
+ Map categoryMap = new HashMap<>();
+
+ String sql_query = "SELECT categories FROM Charities";
+
+ try (Connection conn = connection.getMySqlConnection();
+ Statement stmt = conn.createStatement();
+ ResultSet rs = stmt.executeQuery(sql_query)) {
+
+ while (rs.next()) {
+ String categoriesStr = rs.getString("categories");
+
+ if (categoriesStr != null && !categoriesStr.isEmpty()) {
+ String[] splitCategories = categoriesStr.split(",");
+
+ for (String category : splitCategories) {
+ String trimmed = category.trim();
+
+ if (!trimmed.isEmpty()) {
+ categoryMap.putIfAbsent(trimmed.toLowerCase(), trimmed);
+ }
+ }
+ }
+ }
+ } catch (SQLException e) {
+ e.printStackTrace();
+ throw new RuntimeException("ERROR: Something went wrong while fetching categories from the database.");
+ }
+
+ var categories = new ArrayList<>(categoryMap.values());
+ Collections.sort(categories);
+
+ return categories;
+ }
+
+ public DonationRegistry getDonationFromDB() {
+ DonationRegistry registry = null;
+ Connection conn = null;
+ try {
+ conn = connection.getMySqlConnection();
+ String sql_query =
+ """
+ SELECT
+ d.UUID_Donations,
+ d.amount,
+ d.date,
+ c.UUID_charities,
+ c.org_number,
+ c.charity_name,
+ c.charity_link,
+ c.pre_approved,
+ c.status
+ FROM Donations d
+ JOIN Charities c
+ ON d.Charities_UUID_charities = c.UUID_charities
+ """;
+ Statement stmt = conn.createStatement();
+ ResultSet rs = stmt.executeQuery(sql_query);
+
+ registry = new DonationRegistry();
+ while (rs.next()) {
+ Charity charity =
+ new Charity(
+ rs.getString("UUID_charities"),
+ rs.getString("org_number"),
+ rs.getString("charity_name"),
+ rs.getString("charity_link"),
+ rs.getBoolean("pre_approved"),
+ rs.getString("status"));
+
+ Donation donation =
+ new Donation(
+ rs.getString("UUID_Donations"),
+ rs.getDouble("amount"),
+ rs.getDate("date").toLocalDate(),
+ charity);
+ registry.addDonation(donation);
+ }
+ } catch (SQLException e) {
+ e.printStackTrace();
+ throw new RuntimeException("ERROR: Something went wrong during updating charities table.");
+ }
+ return registry;
+ }
+}
\ No newline at end of file
diff --git a/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/models/Charity.java b/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/models/Charity.java
index fdae199..357e3ec 100644
--- a/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/models/Charity.java
+++ b/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/models/Charity.java
@@ -20,8 +20,8 @@ public class Charity {
/* Name of the charity */
private String name;
- /* Description of the charity's mission and activities */
- private String description;
+ /* URL of the charity */
+ private String url;
/* Is the charity verified? */
private String status;
@@ -31,9 +31,21 @@ public class Charity {
/* Category for the charity */
private String category;
+ /* Description for the charity */
+ private String description;
+
+ /* URL for the logo of the charity */
+ private String logoURL;
+
+ /* Key values for the charity */
+ private String keyValues;
+
/* List that contains the charity's Feedbacks */
private List feedbacks;
+ /* Bytecode for the charity logo */
+ private byte[] logoBlob;
+
/**
* Contructor for creating a new charity. Taylored to match data given from Api. Other attributes
* will just be initialized as empty
@@ -48,7 +60,7 @@ public Charity(
this.UUID = java.util.UUID.randomUUID();
this.org_number = org_number.replaceAll("\\s", "");
this.name = name;
- this.description = "Les mer her: " + link;
+ this.url = link;
this.is_pre_approved = is_pre_approved;
this.status = status;
this.feedbacks = new ArrayList<>();
@@ -74,11 +86,15 @@ public Charity(
this.UUID = UUID.fromString(uuid);
this.org_number = org_number.replaceAll("\\s", "");
this.name = name;
- this.description = link;
+ this.url = link;
this.is_pre_approved = is_pre_approved;
this.status = status;
- this.feedbacks = new ArrayList<>();
this.category = "";
+ this.description = "";
+ this.logoURL = "";
+ this.keyValues = "";
+ this.feedbacks = new ArrayList<>();
+ this.logoBlob = null;
}
/** Getters for the charity's attributes. */
@@ -110,8 +126,24 @@ public String getName() {
return name;
}
+ public String getURL() {
+ return this.url;
+ }
+
public String getDescription() {
- return description;
+ return this.description;
+ }
+
+ public String getLogoURL() {
+ return this.logoURL;
+ }
+
+ public String getKeyValues() {
+ return this.keyValues;
+ }
+
+ public byte[] getLogoBlob() {
+ return this.logoBlob;
}
/** Setter for verification status. This one sets the charity as verified. */
@@ -124,12 +156,35 @@ public void setUnverified() {
this.status = "Veto";
}
+ /** Setter for categories. */
+ public void setCategory(String category) {
+ this.category = category;
+ }
+
+ /** Setter for description. */
+ public void setDescription(String description) {
+ this.description = description;
+ }
+
+ /** Setter for the URL of the charity's logo. */
+ public void setLogoURL(String url) {
+ this.logoURL = url;
+ }
+
+ /** Setter for the charity's key values. */
+ public void setKeyValues(String values) {
+ this.keyValues = values;
+ }
+
+ /** Setter for the charity's logo Blob. */
+ public void setLogoBlob(byte[] logoBlob) {
+ this.logoBlob = logoBlob;
+ }
+
/**
- * Set method for feedbacks. Primarily will be used to set feedbacks taken from database.
- *
- * @param feedbacks
+ * Setter for
*/
- public void setFeedbacks(ArrayList feedbacks) {
+ public void setFeedbacks(ArrayList feedbacks){
this.feedbacks = feedbacks;
}
}
diff --git a/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/scraper/APICharityScraper.java b/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/scraper/APICharityScraper.java
index 89422a1..ac920ac 100644
--- a/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/scraper/APICharityScraper.java
+++ b/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/scraper/APICharityScraper.java
@@ -81,6 +81,9 @@ public CharityRegistry parseJSON(String JSONData) {
CharityRegistry charityRegistry = new CharityRegistry();
for (APICharityData apiCharityData : charityData) {
+ if (apiCharityData.getStatus().equalsIgnoreCase("obs")) {
+ continue;
+ }
Charity charity =
new Charity(
apiCharityData.getOrg_number(),
diff --git a/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/scraper/LogoDownloader.java b/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/scraper/LogoDownloader.java
new file mode 100644
index 0000000..e190699
--- /dev/null
+++ b/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/scraper/LogoDownloader.java
@@ -0,0 +1,54 @@
+package ntnu.systemutvikling.team6.scraper;
+
+import java.io.InputStream;
+import java.net.URL;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+
+/**
+ * Facilitates downloading of .png images from the individual charity's page on IK, converting them
+ * to bytecode (blob), and then back to a .png.
+ */
+public class LogoDownloader {
+
+ /**
+ * Downloads a image from the given URL and converts it to a blob.
+ *
+ * @param imageUrl the URL of the image
+ * @return a blob containing the image data
+ */
+ public static byte[] downloadImageAsBlob(String imageUrl) {
+ if (imageUrl == null || imageUrl.isBlank()) return null;
+
+ try (InputStream in = new URL(imageUrl).openStream()) {
+ return in.readAllBytes();
+ } catch (Exception e) {
+ System.out.println("Error: Something went wrong when downloading the image.");
+ return null;
+ }
+ }
+
+ /**
+ * Converts a blob of image data back to a .png image file.
+ *
+ * @param imageBytes the blob containing the image data
+ * @param fileName the filename of the .png image file
+ */
+ public static void convertBlobToPNG(byte[] imageBytes, String fileName) {
+ if (imageBytes == null) {
+ return;
+ }
+ try {
+ Path folder = Paths.get("target", "logo");
+ Files.createDirectories(folder);
+
+ Path filePath = folder.resolve(fileName + ".png");
+
+ Files.write(filePath, imageBytes);
+
+ } catch (Exception e) {
+ System.out.println("Error: Something went wrong when converting blob to png.");
+ }
+ }
+}
diff --git a/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/scraper/URLCharityScraper.java b/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/scraper/URLCharityScraper.java
new file mode 100644
index 0000000..88be3dd
--- /dev/null
+++ b/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/scraper/URLCharityScraper.java
@@ -0,0 +1,288 @@
+package ntnu.systemutvikling.team6.scraper;
+
+import java.time.Duration;
+import java.util.ArrayList;
+import java.util.List;
+import org.openqa.selenium.By;
+import org.openqa.selenium.WebDriver;
+import org.openqa.selenium.WebElement;
+import org.openqa.selenium.chrome.ChromeDriver;
+import org.openqa.selenium.chrome.ChromeOptions;
+import org.openqa.selenium.support.ui.ExpectedConditions;
+import org.openqa.selenium.support.ui.WebDriverWait;
+
+/**
+ * Class for scraping the description, URL of the logo, string of categories, and key values of the
+ * charities registered in IK.
+ */
+public class URLCharityScraper {
+ private final String url;
+ private final WebDriver driver;
+ private String description;
+ private String logoURL;
+ private final List categories;
+ private final List keyValues;
+
+ /**
+ * Constructor used for production code.
+ *
+ *
It initializes the lists used for categories and keyValues, as well as defining the
+ * parameters used for the selenium Chromium-based browser that does the scraping.
+ *
+ * @param url the URL for the charity's webpage on IK
+ */
+ public URLCharityScraper(String url) {
+ this.categories = new ArrayList<>();
+ this.keyValues = new ArrayList<>();
+
+ ChromeOptions options = new ChromeOptions();
+ options.addArguments("--headless=new");
+ options.addArguments("--window-size=1920,1080");
+ options.addArguments("--disable-gpu");
+ options.addArguments("--no-sandbox");
+ options.addArguments("--disable-dev-shm-usage");
+
+ this.url = url;
+ this.driver = new ChromeDriver(options);
+ }
+
+ /**
+ * Constructor used for testing.
+ *
+ *