├── .gitignore
├── .idea
├── .gitignore
└── misc.xml
├── CHANGELOG
├── LICENSE.md
├── README.md
├── pom.xml
└── src
├── main
└── java
│ └── com
│ └── titusfortner
│ └── logging
│ ├── ChromeDriverLogger.java
│ ├── ChromiumDriverLogger.java
│ ├── DriverLogger.java
│ ├── EdgeDriverLogger.java
│ ├── GeckoDriverLogger.java
│ ├── InternetExplorerDriverLogger.java
│ ├── SafariDriverLogger.java
│ ├── SeleniumFilter.java
│ ├── SeleniumFormatter.java
│ └── SeleniumLogger.java
└── test
└── java
└── com
└── titusfortner
└── logging
├── BaseTest.java
├── ChromeDriverLoggerTest.java
├── EdgeDriverLoggerTest.java
├── GeckoDriverLoggerTest.java
├── InternetExplorerDriverLoggerTest.java
├── SafariDriverLoggerTest.java
├── SeleniumFormatterTest.java
└── SeleniumLoggerTest.java
/.gitignore:
--------------------------------------------------------------------------------
1 | # Compiled files
2 | /out
3 |
4 | # Log file
5 | *.log
6 |
7 | # BlueJ files
8 | *.ctxt
9 |
10 | # Mobile Tools for Java (J2ME)
11 | .mtj.tmp/
12 |
13 | # Package Files #
14 | *.war
15 | *.nar
16 | *.ear
17 | *.zip
18 | *.tar.gz
19 | *.rar
20 |
21 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
22 | hs_err_pid*
23 |
24 | /.idea
25 | /target/
26 |
--------------------------------------------------------------------------------
/.idea/.gitignore:
--------------------------------------------------------------------------------
1 | # Default ignored files
2 | /shelf/
3 | /workspace.xml
4 | # Editor-based HTTP Client requests
5 | /httpRequests/
6 | # Datasource local storage ignored files
7 | /dataSources/
8 | /dataSources.local.xml
9 |
--------------------------------------------------------------------------------
/.idea/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/CHANGELOG:
--------------------------------------------------------------------------------
1 | v2.4.0
2 | ======
3 |
4 | Selenium Logging:
5 | * Require Selenium 4.14.1
6 | * Remove JDK client now that it is Selenium's default
7 | * Remove filtering things that Selenium now handles by default
8 |
9 | v2.3.0
10 | ======
11 |
12 | Selenium Logging:
13 | * Improved filtering out of Base64 values
14 | * Truncate large javascript executions by default
15 | * Implement `setFullLogMessages()` to toggle off truncations where possible
16 |
17 | v2.2.2
18 | ======
19 |
20 | Selenium Logging:
21 | * Workaround a Java bug that hides messages from Throwable
22 | * improve filtering in default formatter by snipping large JS blocks
23 |
24 | v2.2.1
25 | ======
26 |
27 | Selenium Logging:
28 | * Need slf4j-nop so long as AHC is a dependency of Selenium
29 |
30 | v2.2.0
31 | ======
32 |
33 | Selenium Logging:
34 | * Add support to filter out specific classes
35 | * Update default formatter to remove base64 output from response body
36 | * Remove slf4j-nop as a dependency
37 |
38 | v2.1.0
39 | ======
40 |
41 | Selenium Logging:
42 | * Filter out Open Telemetry by default
43 |
44 | Driver Logging:
45 | * Make enable() and all() methods static to match Selenium Logger
46 |
47 | v2.0.0
48 | ======
49 |
50 | Selenium Logging:
51 | * Requires Java 11
52 | * Remove all deprecated classes
53 | * SeleniumFilter is used by default (all Selenium classes now logged by default)
54 |
55 | v1.2.0
56 | ======
57 |
58 | Selenium Logging:
59 | * Updates to work with latest Selenium code
60 | * Create custom formatter for better display of information in logs
61 | * Implement `enable()`, `disable()` and `all()` as convenience methods
62 | * Implemented a default filter with allow lists and block lists; usage is opt-in until 2.0
63 | * Allow setting and getting a custom filter; this overrides the `loggedClasses` implementation
64 | * Deprecation: `geckodriver()`; use `GeckoDriverLogger` constructor directly
65 | * Deprecation: `setFileOutput()` with a new formatter; Use `setFormatter()` if a specific format is desired
66 | * Deprecation: `setHandler()`; Handler is generated dynamically, adjust the specific handler property directly.
67 | * Deprecation: `addLoggedClass()`, `removeLoggedClass()`, `getLoggedClasses()`; Use a filter instead
68 |
69 | Driver Logging:
70 | * Add support for ChromeDriver, EdgeDriver, SafariDriver, InternetExplorerDriver
71 | * All: implement `enable()` to log output to `System.err` at the `INFO` level
72 | * All: allow setting level (except Safari)
73 | * All: allow changing output to a file (except Safari)
74 | * Chromium: support appending to log
75 | * Chromium: support changing timestamp to a readable format
76 | * Firefox: support turning off truncation
77 | * Safari: support getting logging directory location
78 | * Safari: support getting list of files in logging directory
79 | * Support getting the file of the most likely log from logging directory
80 |
81 | v1.1.0
82 | ======
83 | * Add support to turn off Geckodriver logs
84 |
85 | v1.0.0
86 | ======
87 | * Send logs to file
88 | * Change log level
89 | * Add or Remove class names to log
--------------------------------------------------------------------------------
/LICENSE.md:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2023 Titus Fortner
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy of
6 | this software and associated documentation files (the "Software"), to deal in
7 | the Software without restriction, including without limitation the rights to
8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9 | the Software, and to permit persons to whom the Software is furnished to do so,
10 | subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Selenium Logger
2 |
3 | The most useful information for Selenium users gets quickly buried in the logs by default.
4 |
5 | This package is intended to provide a means to quickly get the most useful information...
6 |
7 | If you have...
8 | * :bug: **a bug** — let me know by [Creating an Issue](https://github.com/titusfortner/selenium-logger/issues/new)!
9 | * :bulb: **an idea** — if it helps everyone, [Create a PR](https://github.com/titusfortner/selenium-logger/pulls)!
10 | * :thinking: **a different opinion** — if this library does something that you don't like, copy/paste the code to your own project and edit it however you want!
11 | * :rocket: **a different implementation** — if there's a better way to do things than this library, create your own! (I'll even help you get it published if you want)
12 |
13 | (all made possible because this library uses the [MIT License](LICENSE.md))
14 |
15 | ## Overview
16 |
17 | This project allows you to manage:
18 | * Selenium client logs
19 | * Driver logs
20 |
21 | This project does not manage:
22 | * [Grid logging](https://www.selenium.dev/documentation/grid/configuration/cli_options/#logging)
23 | * Driver logging from drivers started by Grid (see [Selenium Issue #10949](https://github.com/SeleniumHQ/selenium/issues/10949))
24 | * Browser [Console Logs](https://www.selenium.dev/documentation/webdriver/bidirectional/bidirectional_w3c/log/)
25 | * Chrome's [Performance Logging](https://chromedriver.chromium.org/logging/performance-log)
26 |
27 | ### Selenium Logs
28 |
29 | Selenium logs output using the JUL (Java Util Logging) Logger implementation. This selenium-logger library works
30 | directly with JUL code to provide the output you want with only a couple lines of code and no configuration files.
31 |
32 | If you are already working with logging in your project or other libraries and want to access
33 | Selenium logs without requiring this project, see the [Alternatives](#alternatives) section below.
34 |
35 | ### Driver Logs
36 |
37 | The driver logging output is generated by the diver binaries. This library allows you to change the things
38 | the drivers allow you to change, typically including levels and location. See below for more information on the
39 | differences between each of the browser drivers.
40 |
41 | This functionality was not fully supported in Chrome and Edge before Selenium 4.12.1
42 |
43 | Geckodriver logs used to be turned on and sent to console by default, which created a lot of noise.
44 | As of Selenium 4.9.1, logs are now turned off by default.
45 |
46 |
47 | ## Installation
48 |
49 | For Maven users, add this dependency to `pom.xml`
50 | ```
51 |
52 | com.titusfortner
53 | selenium-logger
54 | 2.3.0
55 |
56 | ```
57 |
58 | ## Selenium Usage
59 |
60 | ### Log Level
61 |
62 | By default, Java log level is set to `Level.INFO`.
63 |
64 | Almost everything of interest in Selenium is currently logged with `Level.FINE`,
65 | so using `enable()` changes the level to `FINE`:
66 | ```java
67 | SeleniumLogger.enable();
68 | ```
69 |
70 | To set a specific level (e.g., you want to avoid info logs and just see warnings)
71 | ```java
72 | SeleniumLogger seleniumLogger = new SeleniumLogger();
73 | seleniumLogger.setLevel(Level.WARNING);
74 | ```
75 |
76 | ### Log Output
77 |
78 | By default, logs are sent to the console in `System.err`.
79 | If you want to store the logs in a file, add this to your code:
80 |
81 | ```java
82 | SeleniumLogger seleniumLogger = new SeleniumLogger();
83 | File logFile = new File("/path/to/selenium-log.txt");
84 | seleniumLogger.setFileOutput(file)
85 | ```
86 |
87 | ### Log Filtering
88 |
89 | By default, all Selenium classes are logged, except for the Open Telemetry classes because
90 | [Grid Observability](https://www.selenium.dev/documentation/grid/advanced_features/observability/)
91 | is out of scope for this project.
92 |
93 | To create a list of specific lasses to turn on logs for, based on logger name :
94 | ```java
95 | SeleniumLogger.enable("RemoteWebDriver", "SeleniumManaager")
96 | ```
97 |
98 | ### Advanced Logging
99 |
100 | * Disable all logging with `SeleniumLogger.disable()`
101 | * Turn on logging for all classes, all levels with `SeleniumLogger.all()`
102 | * Create and use your own formatter with `setFormatter()`
103 | * Create and use your own filter with `setFilter()`
104 |
105 | ### Alternatives
106 |
107 | If you are already doing logging in your project or are using other libraries that require
108 | SLF4J (Simple Logging Facade for Java), you can access Selenium's JUL output with `jul-to-slf4j`.
109 | With that library and the `logback-classic` library, you can add Selenium's logger names as desired to the
110 | `src/main/resources/logback.xml` file. Note that this is only an alternative
111 | to Selenium logging, and is independent of the driver logging solutions described in the next section.
112 |
113 |
114 | ## Driver Usage
115 |
116 | These methods will turn on driveer logging;
117 |
118 | `enable()` method sets logger level to `INFO` and output to `System.err`
119 | ```java
120 | ChromeDriverLogger.enable();
121 | EdgeDriverLogger.enable();
122 | GeckoDriverLogger.enable();
123 | InternetExplorerDriverLogger.enable();
124 | SafariDriverLogger().enable();
125 | ```
126 |
127 | `all()` method sets logger level to lowest level and output to `System.err`
128 | ```java
129 | ChromeDriverLogger.all();
130 | EdgeDriverLogger.all();
131 | GeckoDriverLogger.all();
132 | InternetExplorerDriverLogger.all();
133 | ```
134 |
135 | ### Log Level
136 | To set a specific level, or to change an existing log level use the `setLevel()` method.
137 | Setting a level ensures output is sent to `System.err` by default.
138 |
139 | To change to a custom level:
140 | ```java
141 | new ChromeDriverLogger().setLevel(ChromiumDriverLogLevel.DEBUG);
142 | new EdgeDriverLogger().setLevel(ChromiumDriverLogLevel.DEBUG);
143 | new GeckoDriverLogger().setLevel(FirefoxDriverLogLevel.DEBUG);
144 | new InternetExplorerDriverLogger().setLevel(InternetExplorerDriverLogLevel.DEBUG);
145 | ```
146 |
147 | ### Log Output
148 | Sending output to a file ensures level is set to level `INFO`, without needing to call `enable()`.
149 |
150 | To send output to a file:
151 | ```java
152 | new ChromeDriverLogger().setFile(new File("chromedriver.log"));
153 | new EdgeDriverLogger().setFile(new File("edgedriver.log"));
154 | new GeckoDriverLogger().setFile(new File("geckodriver.log"));
155 | new InternetExplorerDriverLogger().setFile(new File("iedriver.log"));
156 | ```
157 |
158 | ### Chromium Specific Logging
159 |
160 | * Append to a log file instead of rewriting it with `appendToLog()`
161 | * Set readable timestamps with `setReadableTimestamp()`
162 |
163 | ### Firefox Specific Logging
164 |
165 | Firefox truncates long lines in the log by default. This can be turned
166 | off with: `new Geckodriver().setTruncate(false)`
167 |
168 | ### Safari Specific Logging
169 |
170 | Safari is special. It does not log to console, only to a file. The
171 | file has a unique name per session and is stored in `"~/Library/Logs/com.apple.WebDriver/"`.
172 | You also cannot change the log level, you get whatever Safari gives you.
173 |
174 | * To get a File object with absolute path to the directory: `getDirectory()`
175 | * To get a list of all files in that directory; `getList()`
176 | * To get the last file in the directory (most likely to be the logs you are looking for): `getFile()`
177 |
178 |
179 |
--------------------------------------------------------------------------------
/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 4.0.0
4 |
5 | com.titusfortner
6 | selenium-logger
7 | 2.5-SNAPSHOT
8 | jar
9 |
10 | Selenium Logger
11 | A basic wrapper to get useful information from Selenium Logging
12 | https://github.com/titusfortner/selenium-logger
13 |
14 |
15 |
16 | MIT
17 | https://opensource.org/license/mit/
18 | repo
19 | a permissive free software license
20 |
21 |
22 |
23 |
24 | Titus on Testing
25 | https://titusfortner.com
26 |
27 |
28 |
29 |
30 | titusfortner
31 | Titus Fortner
32 | titusfortner@gmail.com
33 | https://titusfortner.com/about.html
34 |
35 |
36 |
37 |
38 | scm:git:git@github.com:titusfortner/selenium-logger.git
39 | git@github.com:titusfortner/selenium-logger.git
40 | selenium-logger-2.2.2
41 |
42 |
43 |
44 | 1
45 | 11
46 | 11
47 | UTF-8
48 |
49 |
50 |
51 |
52 | org.seleniumhq.selenium
53 | selenium-java
54 | 4.14.1
55 |
56 |
57 | org.junit.jupiter
58 | junit-jupiter-engine
59 | 5.10.0
60 | test
61 |
62 |
63 | org.slf4j
64 | slf4j-nop
65 | 2.0.6
66 |
67 |
68 |
69 |
70 |
71 | ossrh
72 | https://s01.oss.sonatype.org/service/local/staging/deploy/maven2/
73 |
74 |
75 |
76 |
77 |
78 |
79 | org.sonatype.plugins
80 | nexus-staging-maven-plugin
81 | 1.6.13
82 | true
83 |
84 | ossrh
85 | https://s01.oss.sonatype.org/
86 | true
87 |
88 |
89 |
90 | org.apache.maven.plugins
91 | maven-source-plugin
92 | 3.0.0
93 |
94 |
95 | attach-sources
96 | verify
97 |
98 | jar-no-fork
99 |
100 |
101 |
102 |
103 |
104 | org.apache.maven.plugins
105 | maven-javadoc-plugin
106 | 3.2.0
107 |
108 |
109 | attach-javadocs
110 |
111 | jar
112 |
113 |
114 |
115 |
116 |
117 | org.apache.maven.plugins
118 | maven-gpg-plugin
119 | 1.6
120 |
121 |
122 | sign-artifacts
123 | verify
124 |
125 | sign
126 |
127 |
128 |
129 |
130 |
131 | org.apache.maven.plugins
132 | maven-surefire-plugin
133 | 3.1.2
134 |
135 |
136 |
137 | junit.jupiter.execution.parallel.enabled = true
138 | junit.jupiter.execution.parallel.mode.default = concurrent
139 | junit.jupiter.execution.parallel.config.strategy = fixed
140 | junit.jupiter.execution.parallel.config.fixed.parallelism = ${surefire.parallel}
141 | junit.jupiter.execution.parallel.config.fixed.max-pool-size = ${surefire.parallel}
142 |
143 |
144 |
145 |
146 |
147 |
148 |
--------------------------------------------------------------------------------
/src/main/java/com/titusfortner/logging/ChromeDriverLogger.java:
--------------------------------------------------------------------------------
1 | package com.titusfortner.logging;
2 |
3 | import org.openqa.selenium.chrome.ChromeDriverService;
4 | import org.openqa.selenium.chromium.ChromiumDriverLogLevel;
5 |
6 | public class ChromeDriverLogger extends ChromiumDriverLogger{
7 | public static ChromeDriverLogger enable() {
8 | ChromeDriverLogger logger = new ChromeDriverLogger();
9 | logger.ensureEnabled();
10 | return logger;
11 | }
12 |
13 | public static ChromeDriverLogger all() {
14 | ChromeDriverLogger logger = new ChromeDriverLogger();
15 | logger.setLevel(ChromiumDriverLogLevel.ALL);
16 | return logger;
17 | }
18 |
19 | protected String getLogProperty() {
20 | return ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY;
21 | }
22 |
23 | protected String getReadableTimestampProperty() {
24 | return ChromeDriverService.CHROME_DRIVER_READABLE_TIMESTAMP;
25 | }
26 |
27 | protected String getLogLevelProperty() {
28 | return ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY;
29 | }
30 |
31 | protected String getAppendLogProperty() {
32 | return ChromeDriverService.CHROME_DRIVER_APPEND_LOG_PROPERTY;
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/src/main/java/com/titusfortner/logging/ChromiumDriverLogger.java:
--------------------------------------------------------------------------------
1 | package com.titusfortner.logging;
2 |
3 | import org.openqa.selenium.chromium.ChromiumDriverLogLevel;
4 |
5 | import java.io.File;
6 |
7 | public abstract class ChromiumDriverLogger extends DriverLogger {
8 | protected abstract String getLogLevelProperty();
9 | protected abstract String getAppendLogProperty();
10 | protected abstract String getReadableTimestampProperty();
11 |
12 | public void setLevel(ChromiumDriverLogLevel level) {
13 | System.setProperty(getLogLevelProperty(), level.name());
14 | ensureOutput();
15 | }
16 |
17 | public ChromiumDriverLogLevel getLevel() {
18 | String logLevel = System.getProperty(getLogLevelProperty());
19 | return logLevel == null ? null : ChromiumDriverLogLevel.valueOf(logLevel);
20 | }
21 |
22 | public void appendToLog(File logFile) {
23 | setFile(logFile);
24 | System.setProperty(getAppendLogProperty(), String.valueOf(true));
25 | }
26 |
27 | public void setReadableTimestamp(File logFile) {
28 | setFile(logFile);
29 | System.setProperty(getReadableTimestampProperty(), String.valueOf(true));
30 | }
31 |
32 | protected void ensureLevel() {
33 | if (getLevel() == null) {
34 | setLevel(ChromiumDriverLogLevel.INFO);
35 | }
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/src/main/java/com/titusfortner/logging/DriverLogger.java:
--------------------------------------------------------------------------------
1 | package com.titusfortner.logging;
2 |
3 | import org.openqa.selenium.remote.service.DriverService;
4 |
5 | import java.io.File;
6 |
7 | public abstract class DriverLogger {
8 | protected abstract String getLogProperty();
9 | protected abstract void ensureLevel();
10 |
11 | public void disable() {
12 | System.setProperty(getLogProperty(), DriverService.LOG_NULL);
13 | }
14 |
15 | public String getOutput() {
16 | return System.getProperty(getLogProperty());
17 | }
18 |
19 | public void setFile(File fileName) {
20 | System.setProperty(getLogProperty(), fileName.getAbsolutePath());
21 | ensureLevel();
22 | }
23 |
24 | public File getFile() {
25 | String path = getOutput();
26 | return path == null || !new File(path).isFile() ? null : new File(path);
27 | }
28 |
29 | protected void ensureOutput() {
30 | if (getOutput() == null) {
31 | System.setProperty(getLogProperty(), DriverService.LOG_STDERR);
32 | }
33 | }
34 |
35 | protected void ensureEnabled() {
36 | ensureOutput();
37 | ensureLevel();
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/src/main/java/com/titusfortner/logging/EdgeDriverLogger.java:
--------------------------------------------------------------------------------
1 | package com.titusfortner.logging;
2 |
3 | import org.openqa.selenium.chromium.ChromiumDriverLogLevel;
4 | import org.openqa.selenium.edge.EdgeDriverService;
5 |
6 | public class EdgeDriverLogger extends ChromiumDriverLogger{
7 | public static EdgeDriverLogger enable() {
8 | EdgeDriverLogger logger = new EdgeDriverLogger();
9 | logger.ensureEnabled();
10 | return logger;
11 | }
12 |
13 | public static EdgeDriverLogger all() {
14 | EdgeDriverLogger logger = new EdgeDriverLogger();
15 | logger.setLevel(ChromiumDriverLogLevel.ALL);
16 | return logger;
17 | }
18 |
19 | protected String getLogProperty() {
20 | return EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY;
21 | }
22 |
23 | protected String getReadableTimestampProperty() {
24 | return EdgeDriverService.EDGE_DRIVER_READABLE_TIMESTAMP;
25 | }
26 |
27 | protected String getLogLevelProperty() {
28 | return EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY;
29 | }
30 |
31 | protected String getAppendLogProperty() {
32 | return EdgeDriverService.EDGE_DRIVER_APPEND_LOG_PROPERTY;
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/src/main/java/com/titusfortner/logging/GeckoDriverLogger.java:
--------------------------------------------------------------------------------
1 | package com.titusfortner.logging;
2 |
3 | import org.openqa.selenium.firefox.FirefoxDriverLogLevel;
4 | import org.openqa.selenium.firefox.GeckoDriverService;
5 |
6 | public class GeckoDriverLogger extends DriverLogger{
7 | public static GeckoDriverLogger enable() {
8 | GeckoDriverLogger logger = new GeckoDriverLogger();
9 | logger.ensureEnabled();
10 | return logger;
11 | }
12 |
13 | public static GeckoDriverLogger all() {
14 | GeckoDriverLogger logger = new GeckoDriverLogger();
15 | logger.setLevel(FirefoxDriverLogLevel.TRACE);
16 | return logger;
17 | }
18 |
19 | public void setLevel(FirefoxDriverLogLevel level) {
20 | System.setProperty(getLogLevelProperty(), level.name());
21 | ensureOutput();
22 | }
23 |
24 | public FirefoxDriverLogLevel getLevel() {
25 | String logLevel = System.getProperty(getLogLevelProperty());
26 | return logLevel == null ? null : FirefoxDriverLogLevel.valueOf(logLevel);
27 | }
28 |
29 | public void setTruncate(Boolean truncate) {
30 | System.setProperty(getTruncateProperty(), String.valueOf(!truncate));
31 | ensureLevel();
32 | ensureOutput();
33 | }
34 |
35 | protected void ensureLevel() {
36 | if (getLevel() == null) {
37 | setLevel(FirefoxDriverLogLevel.INFO);
38 | }
39 | }
40 |
41 | protected String getLogProperty() {
42 | return GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY;
43 | }
44 |
45 | private String getLogLevelProperty() {
46 | return GeckoDriverService.GECKO_DRIVER_LOG_LEVEL_PROPERTY;
47 | }
48 |
49 | private String getTruncateProperty() {
50 | return GeckoDriverService.GECKO_DRIVER_LOG_NO_TRUNCATE;
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/src/main/java/com/titusfortner/logging/InternetExplorerDriverLogger.java:
--------------------------------------------------------------------------------
1 | package com.titusfortner.logging;
2 |
3 | import org.openqa.selenium.ie.InternetExplorerDriverLogLevel;
4 | import org.openqa.selenium.ie.InternetExplorerDriverService;
5 |
6 | public class InternetExplorerDriverLogger extends DriverLogger {
7 | public static InternetExplorerDriverLogger enable() {
8 | InternetExplorerDriverLogger logger = new InternetExplorerDriverLogger();
9 | logger.ensureEnabled();
10 | return logger;
11 | }
12 |
13 | public static InternetExplorerDriverLogger all() {
14 | InternetExplorerDriverLogger logger = new InternetExplorerDriverLogger();
15 | logger.setLevel(InternetExplorerDriverLogLevel.TRACE);
16 | return logger;
17 | }
18 |
19 | public void setLevel(InternetExplorerDriverLogLevel level) {
20 | System.setProperty(getLogLevelProperty(), level.name());
21 | ensureOutput();
22 | }
23 |
24 | public InternetExplorerDriverLogLevel getLevel() {
25 | String logLevel = System.getProperty(getLogLevelProperty());
26 | return logLevel == null ? null : InternetExplorerDriverLogLevel.valueOf(logLevel);
27 | }
28 |
29 | protected void ensureLevel() {
30 | if (getLevel() == null) {
31 | setLevel(InternetExplorerDriverLogLevel.INFO);
32 | }
33 | }
34 |
35 | protected String getLogProperty() {
36 | return InternetExplorerDriverService.IE_DRIVER_LOGFILE_PROPERTY;
37 | }
38 |
39 | private String getLogLevelProperty() {
40 | return InternetExplorerDriverService.IE_DRIVER_LOGLEVEL_PROPERTY;
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/src/main/java/com/titusfortner/logging/SafariDriverLogger.java:
--------------------------------------------------------------------------------
1 | package com.titusfortner.logging;
2 |
3 | import com.google.common.annotations.Beta;
4 | import org.openqa.selenium.safari.SafariDriverService;
5 |
6 | import java.io.File;
7 | import java.util.*;
8 |
9 | public class SafariDriverLogger {
10 | public static SafariDriverLogger enable() {
11 | System.setProperty(SafariDriverService.SAFARI_DRIVER_LOGGING, "true");
12 | return new SafariDriverLogger();
13 | }
14 |
15 | public File getDirectory() {
16 | String path = System.getProperty("user.home") + "/Library/Logs/com.apple.WebDriver/";
17 | return new File(path);
18 | }
19 |
20 | public List getList() {
21 | File[] files = getDirectory().listFiles();
22 | return files == null ? null : Arrays.asList(files);
23 | }
24 |
25 | @Beta
26 | public File getFile() {
27 | return getList().stream().max(Comparator.comparingLong(File::lastModified)).orElse(null);
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/src/main/java/com/titusfortner/logging/SeleniumFilter.java:
--------------------------------------------------------------------------------
1 | package com.titusfortner.logging;
2 |
3 | import java.util.ArrayList;
4 | import java.util.List;
5 | import java.util.Objects;
6 | import java.util.logging.Filter;
7 | import java.util.logging.LogRecord;
8 |
9 | public class SeleniumFilter implements Filter {
10 |
11 | private final List logAllowedList = new ArrayList<>(List.of("org.openqa.selenium"));
12 | private final List logBlockList = new ArrayList<>(List.of("opentelemetry"));
13 |
14 | public void addAllowed(String allowed) {
15 | Objects.requireNonNull(allowed);
16 | logAllowedList.add(allowed);
17 | }
18 |
19 | public List getLogAllowedList() {
20 | return logAllowedList;
21 | }
22 |
23 | public void addBlocked(String blocked) {
24 | Objects.requireNonNull(blocked);
25 | logBlockList.add(blocked);
26 | }
27 |
28 | public void clear() {
29 | logAllowedList.clear();
30 | logBlockList.clear();
31 | }
32 |
33 | public List getLogBlockList() {
34 | return logBlockList;
35 | }
36 |
37 | public boolean isLoggable(LogRecord record) {
38 | String loggerName = record.getLoggerName();
39 | return getLogAllowedList().stream().filter(loggerName::contains)
40 | .anyMatch(_a -> getLogBlockList().stream().noneMatch(loggerName::contains));
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/src/main/java/com/titusfortner/logging/SeleniumFormatter.java:
--------------------------------------------------------------------------------
1 | package com.titusfortner.logging;
2 |
3 | import java.io.PrintWriter;
4 | import java.io.StringWriter;
5 | import java.util.Date;
6 | import java.util.logging.Formatter;
7 | import java.util.logging.LogRecord;
8 |
9 | public class SeleniumFormatter extends Formatter {
10 |
11 | @Override
12 | public String format(LogRecord record) {
13 | String source = "";
14 | if (record.getSourceClassName() != null) {
15 | try {
16 | source = record.getSourceClassName().contains("org.openqa.selenium") ? "Selenium [" : "[";
17 | String fullName = record.getSourceClassName().replaceAll("\\$.*", "");
18 | source += Class.forName(fullName).getSimpleName();
19 | } catch (ClassNotFoundException e) {
20 | e.printStackTrace();
21 | }
22 | String methodName = record.getSourceMethodName();
23 | if (methodName != null && !methodName.contains("lambda") && !methodName.equals("log")) {
24 | source += " " + record.getSourceMethodName();
25 | }
26 | } else {
27 | source = record.getLoggerName();
28 | }
29 | String message = formatMessage(record);
30 |
31 | String throwable = "";
32 | if (record.getThrown() != null) {
33 | StringWriter sw = new StringWriter();
34 | PrintWriter pw = new PrintWriter(sw);
35 | pw.println();
36 | record.getThrown().printStackTrace(pw);
37 | pw.close();
38 | throwable = sw.toString();
39 | }
40 | String format = "%1$tF %1$tT %4$s %2$s] %5$s %n";
41 | return String.format(format, new Date(record.getMillis()), source,
42 | record.getLoggerName(), record.getLevel(), message, throwable);
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/src/main/java/com/titusfortner/logging/SeleniumLogger.java:
--------------------------------------------------------------------------------
1 | package com.titusfortner.logging;
2 |
3 | import java.io.File;
4 | import java.io.IOException;
5 | import java.util.Arrays;
6 | import java.util.Objects;
7 | import java.util.logging.ConsoleHandler;
8 | import java.util.logging.FileHandler;
9 | import java.util.logging.Filter;
10 | import java.util.logging.Formatter;
11 | import java.util.logging.Handler;
12 | import java.util.logging.Level;
13 | import java.util.logging.Logger;
14 |
15 | public class SeleniumLogger {
16 | private Handler handler = new ConsoleHandler();
17 | private Level level = Level.INFO;
18 | private Filter filter = new SeleniumFilter();
19 | private Formatter formatter = new SeleniumFormatter();
20 | private File file;
21 | public final Logger rootLogger = Logger.getLogger("");
22 |
23 | /**
24 | * This turns on logger level to FINE
25 | * @return a Selenium Logger
26 | */
27 | public static SeleniumLogger enable() {
28 | SeleniumLogger logger = new SeleniumLogger();
29 | logger.setLevel(Level.FINE);
30 | return logger;
31 | }
32 |
33 | public static SeleniumLogger enable(String name, String... names) {
34 | SeleniumLogger logger = SeleniumLogger.enable();
35 | if (name != null) {
36 | logger.filter(name, names);
37 | }
38 | return logger;
39 | }
40 |
41 | public static SeleniumLogger all() {
42 | SeleniumLogger logger = new SeleniumLogger();
43 | SeleniumFilter seleniumFilter = new SeleniumFilter();
44 | seleniumFilter.addAllowed("");
45 |
46 | logger.setFilter(seleniumFilter);
47 | logger.setLevel(Level.ALL);
48 | return logger;
49 | }
50 |
51 | public SeleniumLogger() {
52 | System.setProperty("webdriver.remote.shorten_log_messages", "true");
53 | updateLogger();
54 | }
55 |
56 | public void setFullLogMessages(Boolean fullLogMessages) {
57 | System.setProperty("webdriver.remote.shorten_log_messages", String.valueOf(!fullLogMessages));
58 | }
59 |
60 | public void setLevel(Level level) {
61 | Objects.requireNonNull(level);
62 | this.level = level;
63 | updateLogger();
64 | }
65 |
66 | public Level getLevel() {
67 | return level;
68 | }
69 |
70 | public void disable() {
71 | this.level = Level.OFF;
72 | updateLogger();
73 | }
74 |
75 | public void setFormatter(Formatter formatter) {
76 | Objects.requireNonNull(formatter);
77 | this.formatter = formatter;
78 | updateLogger();
79 | }
80 |
81 | public Formatter getFormatter() {
82 | return formatter;
83 | }
84 |
85 | public void setFileOutput(File file) {
86 | Objects.requireNonNull(file);
87 | this.file = file;
88 | try {
89 | handler = new FileHandler(file.toString());
90 | } catch (IOException e) {
91 | throw new RuntimeException(e);
92 | }
93 | updateLogger();
94 | }
95 |
96 | public File getFileOutput() {
97 | return file;
98 | }
99 |
100 | public void filter(String name, String... names) {
101 | Objects.requireNonNull(name);
102 | SeleniumFilter filter = new SeleniumFilter();
103 | filter.clear();
104 | filter.addAllowed(name);
105 | Arrays.stream(names).forEach(filter::addAllowed);
106 | setFilter(filter);
107 | }
108 |
109 | public void filterOut(String name, String... names) {
110 | Objects.requireNonNull(name);
111 | SeleniumFilter filter = new SeleniumFilter();
112 | filter.addBlocked(name);
113 | Arrays.stream(names).forEach(filter::addBlocked);
114 | setFilter(filter);
115 | }
116 |
117 | public void setFilter(Filter filter) {
118 | Objects.requireNonNull(filter);
119 | this.filter = filter;
120 | updateLogger();
121 | }
122 |
123 | public Filter getFilter() {
124 | return filter;
125 | }
126 |
127 | private void updateLogger() {
128 | Arrays.stream(rootLogger.getHandlers()).forEach(rootLogger::removeHandler);
129 | rootLogger.setLevel(getLevel());
130 | handler.setFormatter(getFormatter());
131 | handler.setLevel(getLevel());
132 | handler.setFilter(getFilter());
133 | rootLogger.addHandler(handler);
134 | }
135 | }
136 |
--------------------------------------------------------------------------------
/src/test/java/com/titusfortner/logging/BaseTest.java:
--------------------------------------------------------------------------------
1 | package com.titusfortner.logging;
2 |
3 | import org.junit.jupiter.api.AfterEach;
4 | import org.junit.jupiter.api.BeforeEach;
5 | import org.openqa.selenium.WebDriver;
6 | import org.openqa.selenium.chrome.ChromeDriverService;
7 | import org.openqa.selenium.chrome.ChromeOptions;
8 | import org.openqa.selenium.remote.service.DriverFinder;
9 | import org.openqa.selenium.remote.service.DriverService;
10 |
11 | import java.io.ByteArrayOutputStream;
12 | import java.io.IOException;
13 | import java.io.PrintStream;
14 | import java.nio.charset.StandardCharsets;
15 | import java.nio.file.Files;
16 | import java.nio.file.Path;
17 | import java.util.stream.Stream;
18 |
19 | public class BaseTest {
20 | protected WebDriver driver;
21 | protected DriverService service;
22 | private final ByteArrayOutputStream err = new ByteArrayOutputStream();
23 | protected Path logFile;
24 |
25 | @BeforeEach
26 | public void setup() {
27 | System.setErr(new PrintStream(err));
28 | }
29 |
30 | @AfterEach
31 | public void teardown() {
32 | if (driver != null) {
33 | driver.quit();
34 | }
35 | if (service != null) {
36 | service.close();
37 | }
38 | }
39 |
40 | protected String getOutput() {
41 | return err.toString();
42 | }
43 |
44 | protected Boolean logFileContains(String text) {
45 | try (Stream stream = Files.lines(logFile)) {
46 | return stream.anyMatch(line -> line.contains(text));
47 | } catch (IOException e) {
48 | throw new RuntimeException(e);
49 | }
50 | }
51 |
52 | protected Long logFileSize() {
53 | if (logFile == null) {
54 | return null;
55 | }
56 | try (Stream stream = Files.lines(logFile, StandardCharsets.UTF_8)) {
57 | return stream.count();
58 | } catch (IOException e) {
59 | throw new RuntimeException(e);
60 | }
61 | }
62 |
63 | protected void createLogFile(String prefix) {
64 | try {
65 | logFile = Files.createTempFile(prefix + "-logging-", ".log");
66 | logFile.toFile().deleteOnExit();
67 | } catch (IOException e) {
68 | throw new RuntimeException(e);
69 | }
70 | }
71 |
72 | protected void logsWarning() {
73 | try {
74 | ChromeDriverService service = ChromeDriverService.createDefaultService();
75 | ChromeOptions options = new ChromeOptions();
76 | options.setBrowserVersion("banana");
77 | DriverFinder.getPath(service, options, false);
78 | } catch (Throwable e) {
79 | // ignore
80 | }
81 | }
82 | }
83 |
--------------------------------------------------------------------------------
/src/test/java/com/titusfortner/logging/ChromeDriverLoggerTest.java:
--------------------------------------------------------------------------------
1 | package com.titusfortner.logging;
2 |
3 | import org.junit.jupiter.api.Assertions;
4 | import org.junit.jupiter.api.BeforeEach;
5 | import org.junit.jupiter.api.Test;
6 | import org.openqa.selenium.chrome.ChromeDriver;
7 | import org.openqa.selenium.chrome.ChromeDriverService;
8 | import org.openqa.selenium.chrome.ChromeOptions;
9 | import org.openqa.selenium.chromium.ChromiumDriverLogLevel;
10 | import org.openqa.selenium.remote.service.DriverService;
11 |
12 | import java.time.LocalDate;
13 | import java.time.format.DateTimeFormatter;
14 |
15 | public class ChromeDriverLoggerTest extends BaseTest {
16 | private ChromeDriverLogger chromedriverLogger;
17 | @BeforeEach
18 | public void setChromedriverLogger() {
19 | chromedriverLogger = new ChromeDriverLogger();
20 | System.clearProperty(ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY);
21 | System.clearProperty(ChromeDriverService.CHROME_DRIVER_READABLE_TIMESTAMP);
22 | System.clearProperty(ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY);
23 | System.clearProperty(ChromeDriverService.CHROME_DRIVER_APPEND_LOG_PROPERTY);
24 | System.clearProperty(ChromeDriverService.CHROME_DRIVER_VERBOSE_LOG_PROPERTY);
25 | }
26 |
27 | @Test
28 | public void defaultLogsNothing() {
29 | logsInfo();
30 |
31 | Assertions.assertNull(chromedriverLogger.getLevel());
32 | Assertions.assertNull(chromedriverLogger.getOutput());
33 | Assertions.assertEquals("", getOutput());
34 | }
35 |
36 | @Test
37 | public void enableLogsInfo() {
38 | ChromeDriverLogger.enable();
39 |
40 | logsInfo();
41 |
42 | Assertions.assertEquals(ChromiumDriverLogLevel.INFO, chromedriverLogger.getLevel());
43 | Assertions.assertEquals(DriverService.LOG_STDERR, chromedriverLogger.getOutput());
44 | Assertions.assertTrue(getOutput().contains("[INFO]"));
45 | }
46 |
47 | @Test
48 | public void disableLogs() {
49 | ChromeDriverLogger.enable();
50 | chromedriverLogger.disable();
51 |
52 | logsInfo();
53 |
54 | Assertions.assertEquals(ChromiumDriverLogLevel.INFO, chromedriverLogger.getLevel());
55 | Assertions.assertEquals(DriverService.LOG_NULL, chromedriverLogger.getOutput());
56 | Assertions.assertTrue(getOutput().isEmpty());
57 | }
58 |
59 | @Test
60 | public void disableIgnoresLevel() {
61 | chromedriverLogger.setLevel(ChromiumDriverLogLevel.DEBUG);
62 | chromedriverLogger.disable();
63 |
64 | logsInfo();
65 |
66 | Assertions.assertEquals(ChromiumDriverLogLevel.DEBUG, chromedriverLogger.getLevel());
67 | Assertions.assertEquals(DriverService.LOG_NULL, chromedriverLogger.getOutput());
68 | Assertions.assertTrue(getOutput().isEmpty());
69 | }
70 |
71 | @Test
72 | public void setLogLevel() {
73 | chromedriverLogger.setLevel(ChromiumDriverLogLevel.DEBUG);
74 |
75 | logsInfo();
76 |
77 | Assertions.assertEquals(ChromiumDriverLogLevel.DEBUG, chromedriverLogger.getLevel());
78 | Assertions.assertEquals(DriverService.LOG_STDERR, chromedriverLogger.getOutput());
79 | Assertions.assertTrue(getOutput().contains("[DEBUG]"));
80 | }
81 |
82 | @Test
83 | public void setLevelIgnoresOutput() {
84 | createLogFile("chromedriver");
85 | chromedriverLogger.setFile(logFile.toFile());
86 | chromedriverLogger.setLevel(ChromiumDriverLogLevel.DEBUG);
87 |
88 | logsInfo();
89 |
90 | Assertions.assertEquals(ChromiumDriverLogLevel.DEBUG, chromedriverLogger.getLevel());
91 | Assertions.assertEquals(logFile.toString(), chromedriverLogger.getOutput());
92 | Assertions.assertEquals("", getOutput());
93 | Assertions.assertTrue(logFileContains("[DEBUG]"));
94 | }
95 |
96 | @Test
97 | public void setLogFile() {
98 | createLogFile("chromedriver");
99 | chromedriverLogger.setFile(logFile.toFile());
100 |
101 | logsInfo();
102 |
103 | Assertions.assertEquals(ChromiumDriverLogLevel.INFO, chromedriverLogger.getLevel());
104 | Assertions.assertEquals(logFile.toString(), chromedriverLogger.getOutput());
105 | Assertions.assertEquals("", getOutput());
106 | Assertions.assertTrue(logFileContains("[INFO]"));
107 | }
108 |
109 | @Test
110 | public void setFileIgnoresLevel() {
111 | chromedriverLogger.setLevel(ChromiumDriverLogLevel.DEBUG);
112 | createLogFile("chromedriver");
113 | chromedriverLogger.setFile(logFile.toFile());
114 |
115 | logsInfo();
116 |
117 | Assertions.assertEquals(ChromiumDriverLogLevel.DEBUG, chromedriverLogger.getLevel());
118 | Assertions.assertEquals(logFile.toString(), chromedriverLogger.getOutput());
119 | Assertions.assertTrue(logFileContains("[DEBUG]"));
120 | }
121 |
122 | @Test
123 | public void allLogLevels() {
124 | chromedriverLogger.all();
125 |
126 | logsInfo();
127 |
128 | Assertions.assertEquals(ChromiumDriverLogLevel.ALL, chromedriverLogger.getLevel());
129 | Assertions.assertEquals(DriverService.LOG_STDERR, chromedriverLogger.getOutput());
130 | Assertions.assertTrue(getOutput().contains("[DEBUG]"));
131 | }
132 |
133 | @Test
134 | public void allLogsIgnoresOutput() {
135 | createLogFile("chromedriver");
136 | chromedriverLogger.setFile(logFile.toFile());
137 | chromedriverLogger.all();
138 |
139 | logsInfo();
140 |
141 | Assertions.assertEquals(ChromiumDriverLogLevel.ALL, chromedriverLogger.getLevel());
142 | Assertions.assertEquals(logFile.toString(), chromedriverLogger.getOutput());
143 | Assertions.assertFalse(getOutput().contains("[DEBUG]"));
144 | }
145 |
146 | @Test
147 | public void withoutAppend() {
148 | createLogFile("chromedriver");
149 | chromedriverLogger.setFile(logFile.toFile());
150 |
151 | logsStartStop();
152 |
153 | long initialSize = logFileSize();
154 |
155 | logsStartStop();
156 |
157 | Assertions.assertEquals(logFileSize(), initialSize);
158 | }
159 |
160 | @Test
161 | public void appendLogs() {
162 | createLogFile("chromedriver-append");
163 | chromedriverLogger.appendToLog(logFile.toFile());
164 |
165 | logsStartStop();
166 |
167 | long initialSize = logFileSize();
168 |
169 | logsStartStop();
170 |
171 | Assertions.assertEquals(initialSize*2, logFileSize());
172 | }
173 |
174 | @Test
175 | public void setReadableTimestamp() {
176 | createLogFile("chromedriver");
177 | chromedriverLogger.setReadableTimestamp(logFile.toFile());
178 |
179 | logsInfo();
180 |
181 | DateTimeFormatter dtf = DateTimeFormatter.ofPattern("MM-dd-uuuu ");
182 | LocalDate localDate = LocalDate.now();
183 | Assertions.assertTrue(logFileContains("[" + dtf.format(localDate)));
184 | }
185 |
186 | private void logsInfo() {
187 | ChromeOptions options = new ChromeOptions();
188 | options.addArguments("--headless=new");
189 | driver = new ChromeDriver(options);
190 | }
191 |
192 | private void logsStartStop() {
193 | logsInfo();
194 | driver.quit();
195 | }
196 | }
197 |
--------------------------------------------------------------------------------
/src/test/java/com/titusfortner/logging/EdgeDriverLoggerTest.java:
--------------------------------------------------------------------------------
1 | package com.titusfortner.logging;
2 |
3 | import org.junit.jupiter.api.Assertions;
4 | import org.junit.jupiter.api.BeforeEach;
5 | import org.junit.jupiter.api.Test;
6 | import org.openqa.selenium.chrome.ChromeDriver;
7 | import org.openqa.selenium.chrome.ChromeOptions;
8 | import org.openqa.selenium.edge.EdgeDriver;
9 | import org.openqa.selenium.edge.EdgeDriverService;
10 | import org.openqa.selenium.chromium.ChromiumDriverLogLevel;
11 | import org.openqa.selenium.edge.EdgeOptions;
12 | import org.openqa.selenium.remote.service.DriverService;
13 |
14 | import java.io.IOException;
15 | import java.time.LocalDate;
16 | import java.time.format.DateTimeFormatter;
17 |
18 | public class EdgeDriverLoggerTest extends BaseTest {
19 | private EdgeDriverLogger edgedriverLogger;
20 | @BeforeEach
21 | public void setEdgedriverLogger() {
22 | edgedriverLogger = new EdgeDriverLogger();
23 | System.clearProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY);
24 | System.clearProperty(EdgeDriverService.EDGE_DRIVER_READABLE_TIMESTAMP);
25 | System.clearProperty(EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY);
26 | System.clearProperty(EdgeDriverService.EDGE_DRIVER_APPEND_LOG_PROPERTY);
27 | System.clearProperty(EdgeDriverService.EDGE_DRIVER_VERBOSE_LOG_PROPERTY);
28 | }
29 |
30 | @Test
31 | public void defaultLogsNothing() {
32 | logsInfo();
33 |
34 | Assertions.assertNull(edgedriverLogger.getLevel());
35 | Assertions.assertNull(edgedriverLogger.getOutput());
36 | Assertions.assertEquals("", getOutput());
37 | }
38 |
39 | @Test
40 | public void enableLogsInfo() {
41 | EdgeDriverLogger.enable();
42 |
43 | logsInfo();
44 |
45 | Assertions.assertEquals(ChromiumDriverLogLevel.INFO, edgedriverLogger.getLevel());
46 | Assertions.assertEquals(DriverService.LOG_STDERR, edgedriverLogger.getOutput());
47 | Assertions.assertTrue(getOutput().contains("[INFO]"));
48 | }
49 |
50 | @Test
51 | public void disableLogs() {
52 | EdgeDriverLogger.enable();
53 | edgedriverLogger.disable();
54 |
55 | logsInfo();
56 |
57 | Assertions.assertEquals(ChromiumDriverLogLevel.INFO, edgedriverLogger.getLevel());
58 | Assertions.assertEquals(DriverService.LOG_NULL, edgedriverLogger.getOutput());
59 | Assertions.assertTrue(getOutput().isEmpty());
60 | }
61 |
62 | @Test
63 | public void disableIgnoresLevel() {
64 | edgedriverLogger.setLevel(ChromiumDriverLogLevel.DEBUG);
65 | edgedriverLogger.disable();
66 |
67 | logsInfo();
68 |
69 | Assertions.assertEquals(ChromiumDriverLogLevel.DEBUG, edgedriverLogger.getLevel());
70 | Assertions.assertEquals(DriverService.LOG_NULL, edgedriverLogger.getOutput());
71 | Assertions.assertTrue(getOutput().isEmpty());
72 | }
73 |
74 | @Test
75 | public void setLogLevel() {
76 | edgedriverLogger.setLevel(ChromiumDriverLogLevel.DEBUG);
77 |
78 | logsInfo();
79 |
80 | Assertions.assertEquals(ChromiumDriverLogLevel.DEBUG, edgedriverLogger.getLevel());
81 | Assertions.assertEquals(DriverService.LOG_STDERR, edgedriverLogger.getOutput());
82 | Assertions.assertTrue(getOutput().contains("[DEBUG]"));
83 | }
84 |
85 | @Test
86 | public void setLevelIgnoresOutput() {
87 | createLogFile("edgedriver");
88 | edgedriverLogger.setFile(logFile.toFile());
89 | edgedriverLogger.setLevel(ChromiumDriverLogLevel.DEBUG);
90 |
91 | logsInfo();
92 |
93 | Assertions.assertEquals(ChromiumDriverLogLevel.DEBUG, edgedriverLogger.getLevel());
94 | Assertions.assertEquals(logFile.toString(), edgedriverLogger.getOutput());
95 | Assertions.assertEquals("", getOutput());
96 | Assertions.assertTrue(logFileContains("[DEBUG]"));
97 | }
98 |
99 | @Test
100 | public void setLogFile() {
101 | createLogFile("edgedriver");
102 | edgedriverLogger.setFile(logFile.toFile());
103 |
104 | logsInfo();
105 |
106 | Assertions.assertEquals(ChromiumDriverLogLevel.INFO, edgedriverLogger.getLevel());
107 | Assertions.assertEquals(logFile.toString(), edgedriverLogger.getOutput());
108 | Assertions.assertEquals("", getOutput());
109 | Assertions.assertTrue(logFileContains("[INFO]"));
110 | }
111 |
112 | @Test
113 | public void setFileIgnoresLevel() {
114 | edgedriverLogger.setLevel(ChromiumDriverLogLevel.DEBUG);
115 | createLogFile("edgedriver");
116 | edgedriverLogger.setFile(logFile.toFile());
117 |
118 | logsInfo();
119 |
120 | Assertions.assertEquals(ChromiumDriverLogLevel.DEBUG, edgedriverLogger.getLevel());
121 | Assertions.assertEquals(logFile.toString(), edgedriverLogger.getOutput());
122 | Assertions.assertTrue(logFileContains("[DEBUG]"));
123 | }
124 |
125 | @Test
126 | public void allLogLevels() {
127 | edgedriverLogger.all();
128 |
129 | logsInfo();
130 |
131 | Assertions.assertEquals(ChromiumDriverLogLevel.ALL, edgedriverLogger.getLevel());
132 | Assertions.assertEquals(DriverService.LOG_STDERR, edgedriverLogger.getOutput());
133 | Assertions.assertTrue(getOutput().contains("[DEBUG]"));
134 | }
135 |
136 | @Test
137 | public void allLogsIgnoresOutput() {
138 | createLogFile("edgedriver");
139 | edgedriverLogger.setFile(logFile.toFile());
140 | edgedriverLogger.all();
141 |
142 | logsInfo();
143 |
144 | Assertions.assertEquals(ChromiumDriverLogLevel.ALL, edgedriverLogger.getLevel());
145 | Assertions.assertEquals(logFile.toString(), edgedriverLogger.getOutput());
146 | Assertions.assertFalse(getOutput().contains("[DEBUG]"));
147 | }
148 |
149 | @Test
150 | public void withoutAppend() {
151 | createLogFile("edgedriver");
152 | edgedriverLogger.setFile(logFile.toFile());
153 |
154 | logsStartStop();
155 |
156 | long initialSize = logFileSize();
157 |
158 | logsStartStop();
159 |
160 | Assertions.assertEquals(logFileSize(), initialSize);
161 | }
162 |
163 | @Test
164 | public void appendLogs() {
165 | createLogFile("edgedriver-append");
166 | edgedriverLogger.appendToLog(logFile.toFile());
167 |
168 | logsStartStop();
169 |
170 | long initialSize = logFileSize();
171 |
172 | logsStartStop();
173 |
174 | Assertions.assertEquals(initialSize*2, logFileSize());
175 | }
176 |
177 | @Test
178 | public void setReadableTimestamp() {
179 | createLogFile("edgedriver");
180 | edgedriverLogger.setReadableTimestamp(logFile.toFile());
181 |
182 | logsInfo();
183 |
184 | DateTimeFormatter dtf = DateTimeFormatter.ofPattern("MM-dd-uuuu ");
185 | LocalDate localDate = LocalDate.now();
186 | Assertions.assertTrue(logFileContains("[" + dtf.format(localDate)));
187 | }
188 |
189 | private void logsInfo() {
190 | EdgeOptions options = new EdgeOptions();
191 | options.addArguments("--headless=new");
192 | driver = new EdgeDriver(options);
193 | }
194 |
195 | private void logsStartStop() {
196 | logsInfo();
197 | driver.quit();
198 | }
199 | }
200 |
--------------------------------------------------------------------------------
/src/test/java/com/titusfortner/logging/GeckoDriverLoggerTest.java:
--------------------------------------------------------------------------------
1 | package com.titusfortner.logging;
2 |
3 | import org.junit.jupiter.api.Assertions;
4 | import org.junit.jupiter.api.BeforeEach;
5 | import org.junit.jupiter.api.Test;
6 | import org.openqa.selenium.firefox.FirefoxDriver;
7 | import org.openqa.selenium.firefox.FirefoxDriverLogLevel;
8 | import org.openqa.selenium.firefox.FirefoxOptions;
9 | import org.openqa.selenium.firefox.GeckoDriverService;
10 | import org.openqa.selenium.remote.service.DriverService;
11 |
12 | import java.io.IOException;
13 |
14 | public class GeckoDriverLoggerTest extends BaseTest {
15 | private GeckoDriverLogger geckodriverLogger;
16 | @BeforeEach
17 | public void setFirefoxDriverLogger() {
18 | geckodriverLogger = new GeckoDriverLogger();
19 | System.clearProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY);
20 | System.clearProperty(GeckoDriverService.GECKO_DRIVER_LOG_LEVEL_PROPERTY);
21 | }
22 |
23 | @Test
24 | public void defaultLogsNothing() {
25 | logsInfo();
26 |
27 | Assertions.assertNull(geckodriverLogger.getLevel());
28 | Assertions.assertNull(geckodriverLogger.getOutput());
29 | Assertions.assertEquals("", getOutput());
30 | }
31 |
32 | @Test
33 | public void enableLogsInfo() {
34 | GeckoDriverLogger.enable();
35 |
36 | logsInfo();
37 |
38 | Assertions.assertEquals(FirefoxDriverLogLevel.INFO, geckodriverLogger.getLevel());
39 | Assertions.assertEquals(DriverService.LOG_STDERR, geckodriverLogger.getOutput());
40 | Assertions.assertTrue(getOutput().contains("\tINFO\t"));
41 | }
42 |
43 | @Test
44 | public void disableGeckoDriverOutput() {
45 | GeckoDriverLogger.enable();
46 | geckodriverLogger.disable();
47 |
48 | logsInfo();
49 |
50 | Assertions.assertEquals(DriverService.LOG_NULL, geckodriverLogger.getOutput());
51 | Assertions.assertEquals("", getOutput());
52 | }
53 |
54 | @Test
55 | public void disableIgnoresLevel() {
56 | geckodriverLogger.setLevel(FirefoxDriverLogLevel.DEBUG);
57 | geckodriverLogger.disable();
58 |
59 | Assertions.assertEquals(FirefoxDriverLogLevel.DEBUG, geckodriverLogger.getLevel());
60 | }
61 |
62 | @Test
63 | public void setLevelEnables() {
64 | geckodriverLogger.setLevel(FirefoxDriverLogLevel.DEBUG);
65 |
66 | logsDebug();
67 |
68 | Assertions.assertEquals(FirefoxDriverLogLevel.DEBUG, geckodriverLogger.getLevel());
69 | Assertions.assertEquals(DriverService.LOG_STDERR, geckodriverLogger.getOutput());
70 | Assertions.assertTrue(getOutput().contains("\tDEBUG\t"));
71 | }
72 |
73 | @Test
74 | public void setLevelIgnoresOutput() {
75 | createLogFile("firefoxDriver");
76 | geckodriverLogger.setFile(logFile.toFile());
77 |
78 | geckodriverLogger.setLevel(FirefoxDriverLogLevel.DEBUG);
79 |
80 | Assertions.assertEquals(FirefoxDriverLogLevel.DEBUG, geckodriverLogger.getLevel());
81 | Assertions.assertEquals(logFile.toString(), geckodriverLogger.getOutput());
82 | }
83 |
84 | @Test
85 | public void setsFile() {
86 | createLogFile("firefoxDriver");
87 | geckodriverLogger.setFile(logFile.toFile());
88 |
89 | logsInfo();
90 |
91 | Assertions.assertEquals(FirefoxDriverLogLevel.INFO, geckodriverLogger.getLevel());
92 | Assertions.assertEquals(logFile.toString(), geckodriverLogger.getOutput());
93 | Assertions.assertEquals("", getOutput());
94 | Assertions.assertTrue(logFileContains("\tINFO\t"));
95 | }
96 |
97 | @Test
98 | public void setFileIgnoresLevel() {
99 | geckodriverLogger.setLevel(FirefoxDriverLogLevel.DEBUG);
100 | createLogFile("firefoxDriver");
101 | geckodriverLogger.setFile(logFile.toFile());
102 |
103 | Assertions.assertEquals(FirefoxDriverLogLevel.DEBUG, geckodriverLogger.getLevel());
104 | Assertions.assertEquals(logFile.toString(), geckodriverLogger.getOutput());
105 | Assertions.assertEquals(logFile.toFile(), geckodriverLogger.getFile());
106 | }
107 |
108 | @Test
109 | public void allLogLevels() {
110 | geckodriverLogger.all();
111 |
112 | logsDebug();
113 |
114 | Assertions.assertEquals(FirefoxDriverLogLevel.TRACE, geckodriverLogger.getLevel());
115 | Assertions.assertEquals(DriverService.LOG_STDERR, geckodriverLogger.getOutput());
116 | Assertions.assertTrue(getOutput().contains("\tTRACE\t"));
117 | }
118 |
119 | @Test
120 | public void allLogsIgnoresOutput() {
121 | createLogFile("firefoxDriver");
122 | geckodriverLogger.setFile(logFile.toFile());
123 | geckodriverLogger.all();
124 |
125 | logsDebug();
126 |
127 | Assertions.assertEquals(FirefoxDriverLogLevel.TRACE, geckodriverLogger.getLevel());
128 | Assertions.assertEquals(logFile.toString(), geckodriverLogger.getOutput());
129 | Assertions.assertFalse(getOutput().contains("\tTRACE\t"));
130 | }
131 |
132 | @Test
133 | public void truncates() {
134 | geckodriverLogger.setTruncate(true);
135 |
136 | logsDebug();
137 |
138 | Assertions.assertEquals(FirefoxDriverLogLevel.INFO, geckodriverLogger.getLevel());
139 | Assertions.assertEquals(DriverService.LOG_STDERR, geckodriverLogger.getOutput());
140 | Assertions.assertTrue(getOutput().contains(" ... "));
141 | }
142 |
143 | @Test
144 | public void doesNotTruncate() {
145 | geckodriverLogger.setTruncate(false);
146 |
147 | logsDebug();
148 |
149 | Assertions.assertEquals(FirefoxDriverLogLevel.INFO, geckodriverLogger.getLevel());
150 | Assertions.assertEquals(DriverService.LOG_STDERR, geckodriverLogger.getOutput());
151 | Assertions.assertFalse(getOutput().contains(" ... "));
152 | }
153 |
154 | private void logsInfo() {
155 | service = new GeckoDriverService.Builder().build();
156 | try {
157 | service.start();
158 | } catch (IOException e) {
159 | // ignore
160 | }
161 | }
162 |
163 | private void logsDebug() {
164 | FirefoxOptions options = new FirefoxOptions();
165 | options.addArguments("-headless");
166 | driver = new FirefoxDriver(options);
167 | }
168 | }
169 |
--------------------------------------------------------------------------------
/src/test/java/com/titusfortner/logging/InternetExplorerDriverLoggerTest.java:
--------------------------------------------------------------------------------
1 | package com.titusfortner.logging;
2 |
3 | import org.junit.jupiter.api.Assertions;
4 | import org.junit.jupiter.api.BeforeEach;
5 | import org.junit.jupiter.api.Test;
6 | import org.junit.jupiter.api.condition.EnabledOnOs;
7 | import org.junit.jupiter.api.condition.OS;
8 | import org.openqa.selenium.ie.InternetExplorerDriver;
9 | import org.openqa.selenium.ie.InternetExplorerDriverLogLevel;
10 | import org.openqa.selenium.ie.InternetExplorerDriverService;
11 | import org.openqa.selenium.remote.service.DriverService;
12 |
13 | import java.time.Year;
14 |
15 | @EnabledOnOs(OS.WINDOWS)
16 | public class InternetExplorerDriverLoggerTest extends BaseTest {
17 | private InternetExplorerDriverLogger internetExplorerDriverLogger;
18 |
19 | @BeforeEach
20 | public void setIeDriverLogger() {
21 | internetExplorerDriverLogger = new InternetExplorerDriverLogger();
22 | System.clearProperty(InternetExplorerDriverService.IE_DRIVER_LOGFILE_PROPERTY);
23 | System.clearProperty(InternetExplorerDriverService.IE_DRIVER_LOGLEVEL_PROPERTY);
24 | }
25 |
26 | @Test
27 | public void defaultLogsNothing() {
28 | logsInfo();
29 |
30 | Assertions.assertNull(internetExplorerDriverLogger.getLevel());
31 | Assertions.assertNull(internetExplorerDriverLogger.getOutput());
32 | Assertions.assertTrue(getOutput().isEmpty());
33 | }
34 |
35 | @Test
36 | public void enableLogsInfo() {
37 | InternetExplorerDriverLogger.enable();
38 |
39 | logsInfo();
40 |
41 | Assertions.assertEquals(InternetExplorerDriverLogLevel.INFO, internetExplorerDriverLogger.getLevel());
42 | Assertions.assertEquals(DriverService.LOG_STDERR, internetExplorerDriverLogger.getOutput());
43 | Assertions.assertTrue(getOutput().contains("I " + Year.now()));
44 | }
45 |
46 | @Test
47 | public void disableLogs() {
48 | InternetExplorerDriverLogger.enable();
49 | internetExplorerDriverLogger.disable();
50 |
51 | logsInfo();
52 |
53 | Assertions.assertEquals(DriverService.LOG_NULL, internetExplorerDriverLogger.getOutput());
54 | Assertions.assertEquals("", getOutput());
55 | }
56 |
57 | @Test
58 | public void disableIgnoresLevel() {
59 | internetExplorerDriverLogger.setLevel(InternetExplorerDriverLogLevel.DEBUG);
60 | internetExplorerDriverLogger.disable();
61 |
62 | Assertions.assertEquals(InternetExplorerDriverLogLevel.DEBUG, internetExplorerDriverLogger.getLevel());
63 | }
64 |
65 | @Test
66 | public void setLogLevel() {
67 | internetExplorerDriverLogger.setLevel(InternetExplorerDriverLogLevel.DEBUG);
68 |
69 | logsInfo();
70 |
71 | Assertions.assertEquals(InternetExplorerDriverLogLevel.DEBUG, internetExplorerDriverLogger.getLevel());
72 | Assertions.assertEquals(DriverService.LOG_STDERR, internetExplorerDriverLogger.getOutput());
73 | Assertions.assertTrue(getOutput().contains("D " + Year.now()));
74 | }
75 |
76 | @Test
77 | public void setLevelIgnoresOutput() {
78 | createLogFile("ieDriver");
79 | internetExplorerDriverLogger.setFile(logFile.toFile());
80 |
81 | internetExplorerDriverLogger.setLevel(InternetExplorerDriverLogLevel.DEBUG);
82 |
83 | Assertions.assertEquals(InternetExplorerDriverLogLevel.DEBUG, internetExplorerDriverLogger.getLevel());
84 | Assertions.assertEquals(logFile.toString(), internetExplorerDriverLogger.getOutput());
85 | }
86 |
87 | @Test
88 | public void setLogFile() {
89 | createLogFile("ieDriver");
90 | internetExplorerDriverLogger.setFile(logFile.toFile());
91 |
92 | logsInfo();
93 |
94 | Assertions.assertEquals(InternetExplorerDriverLogLevel.INFO, internetExplorerDriverLogger.getLevel());
95 | Assertions.assertEquals(logFile.toString(), internetExplorerDriverLogger.getOutput());
96 | Assertions.assertEquals("", getOutput());
97 | Assertions.assertTrue(logFileContains("I " + Year.now()));
98 | }
99 |
100 | @Test
101 | public void setFileIgnoresLevel() {
102 | internetExplorerDriverLogger.setLevel(InternetExplorerDriverLogLevel.DEBUG);
103 | createLogFile("ieDriver");
104 | internetExplorerDriverLogger.setFile(logFile.toFile());
105 |
106 | Assertions.assertEquals(InternetExplorerDriverLogLevel.DEBUG, internetExplorerDriverLogger.getLevel());
107 | Assertions.assertEquals(logFile.toString(), internetExplorerDriverLogger.getOutput());
108 | Assertions.assertEquals(logFile.toFile(), internetExplorerDriverLogger.getFile());
109 | }
110 |
111 | @Test
112 | public void allLogLevels() {
113 | internetExplorerDriverLogger.all();
114 |
115 | logsInfo();
116 |
117 | Assertions.assertEquals(InternetExplorerDriverLogLevel.TRACE, internetExplorerDriverLogger.getLevel());
118 | Assertions.assertEquals(DriverService.LOG_STDERR, internetExplorerDriverLogger.getOutput());
119 | Assertions.assertTrue(getOutput().contains("T " + Year.now()));
120 | }
121 |
122 | @Test
123 | public void allLogsIgnoresOutput() {
124 | createLogFile("ieDriver");
125 | internetExplorerDriverLogger.setFile(logFile.toFile());
126 | internetExplorerDriverLogger.all();
127 |
128 | logsInfo();
129 |
130 | Assertions.assertEquals(InternetExplorerDriverLogLevel.TRACE, internetExplorerDriverLogger.getLevel());
131 | Assertions.assertEquals(logFile.toString(), internetExplorerDriverLogger.getOutput());
132 | Assertions.assertFalse(getOutput().contains("T " + Year.now()));
133 | }
134 |
135 | private void logsInfo() {
136 | driver = new InternetExplorerDriver();
137 | }
138 | }
139 |
--------------------------------------------------------------------------------
/src/test/java/com/titusfortner/logging/SafariDriverLoggerTest.java:
--------------------------------------------------------------------------------
1 | package com.titusfortner.logging;
2 |
3 | import org.junit.jupiter.api.Assertions;
4 | import org.junit.jupiter.api.BeforeEach;
5 | import org.junit.jupiter.api.Test;
6 | import org.junit.jupiter.api.condition.EnabledOnOs;
7 | import org.junit.jupiter.api.condition.OS;
8 | import org.openqa.selenium.safari.SafariDriver;
9 | import org.openqa.selenium.safari.SafariDriverService;
10 |
11 | @EnabledOnOs(OS.MAC)
12 | public class SafariDriverLoggerTest extends BaseTest {
13 | private SafariDriverLogger safariDriverLogger;
14 |
15 | @BeforeEach
16 | public void enableLogging() {
17 | safariDriverLogger = new SafariDriverLogger();
18 | System.clearProperty(SafariDriverService.SAFARI_DRIVER_LOGGING);
19 | }
20 |
21 | @Test
22 | public void defaultIsNoLogging() {
23 | int before = safariDriverLogger.getList().size();
24 |
25 | driver = new SafariDriver();
26 |
27 | Assertions.assertEquals(before, safariDriverLogger.getList().size());
28 | }
29 |
30 | @Test
31 | public void enableLogs() {
32 | SafariDriverLogger.enable();
33 |
34 | int before = safariDriverLogger.getList().size();
35 | driver = new SafariDriver();
36 |
37 | Assertions.assertEquals(before + 1, safariDriverLogger.getList().size());
38 | }
39 |
40 | @Test
41 | public void getFile() {
42 | SafariDriverLogger.enable();
43 |
44 | driver = new SafariDriver();
45 |
46 | logFile = safariDriverLogger.getFile().toPath();
47 | Assertions.assertTrue(logFileContains("AutomationProtocol: SEND"));
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/src/test/java/com/titusfortner/logging/SeleniumFormatterTest.java:
--------------------------------------------------------------------------------
1 | package com.titusfortner.logging;
2 |
3 | import com.google.common.io.Resources;
4 | import org.junit.jupiter.api.Assertions;
5 | import org.junit.jupiter.api.Test;
6 | import org.openqa.selenium.*;
7 | import org.openqa.selenium.firefox.FirefoxDriver;
8 | import org.openqa.selenium.firefox.HasFullPageScreenshot;
9 | import org.openqa.selenium.print.PrintOptions;
10 |
11 | import java.io.IOException;
12 | import java.net.URL;
13 | import java.nio.charset.StandardCharsets;
14 | import java.util.Objects;
15 | import java.util.logging.SimpleFormatter;
16 |
17 | public class SeleniumFormatterTest extends BaseTest {
18 | private final SeleniumLogger seleniumLogger = new SeleniumLogger();
19 |
20 | @Test
21 | public void setFormatter() {
22 | seleniumLogger.enable().setFormatter(new SimpleFormatter());
23 |
24 | logsWarning();
25 |
26 | String fine = "chrome banana not available for download";
27 | Assertions.assertTrue(getOutput().contains(fine));
28 | }
29 |
30 | @Test
31 | public void getFormatter() {
32 | Assertions.assertSame(seleniumLogger.getFormatter().getClass(), SeleniumFormatter.class);
33 | }
34 |
35 | @Test
36 | public void defaultFormattingTruncates() throws IOException {
37 | SeleniumLogger.enable();
38 |
39 | driver = new FirefoxDriver();
40 | driver.get("https://www.selenium.dev");
41 |
42 | ((PrintsPage) driver).print(new PrintOptions());
43 | ((HasFullPageScreenshot) driver).getFullPageScreenshotAs(OutputType.BASE64);
44 |
45 | WebElement element = driver.findElement(By.tagName("body"));
46 | ((JavascriptExecutor) driver).executeScript(isDisplayedScript(), element);
47 |
48 | Assertions.assertTrue(getOutput().contains("printPage response suppressed"));
49 | Assertions.assertTrue(getOutput().contains("fullPageScreenshot response suppressed"));
50 | Assertions.assertTrue(getOutput().contains("{script=/* isDisplayed */return (function(){ret..."));
51 | }
52 |
53 | @Test
54 | public void removeTruncation() throws IOException {
55 | SeleniumLogger.enable().setFullLogMessages(true);
56 |
57 | driver = new FirefoxDriver();
58 |
59 | WebElement element = driver.findElement(By.tagName("body"));
60 | ((JavascriptExecutor) driver).executeScript(isDisplayedScript(), element);
61 |
62 | Assertions.assertFalse(getOutput().contains("{script=/* isDisplayed */return (function(){ret..."));
63 | }
64 |
65 | private String isDisplayedScript() throws IOException {
66 | URL resource = getClass().getResource("/org/openqa/selenium/remote/isDisplayed.js");
67 | String function = Resources.toString(Objects.requireNonNull(resource), StandardCharsets.UTF_8);
68 | String format = "/* isDisplayed */return (%s).apply(null, arguments);";
69 | return String.format(format, function);
70 | }
71 | }
72 |
--------------------------------------------------------------------------------
/src/test/java/com/titusfortner/logging/SeleniumLoggerTest.java:
--------------------------------------------------------------------------------
1 | package com.titusfortner.logging;
2 |
3 | import org.junit.jupiter.api.Assertions;
4 | import org.junit.jupiter.api.BeforeEach;
5 | import org.junit.jupiter.api.Test;
6 | import org.openqa.selenium.chrome.ChromeDriver;
7 | import org.openqa.selenium.chrome.ChromeDriverService;
8 | import org.openqa.selenium.chrome.ChromeOptions;
9 | import org.openqa.selenium.remote.RemoteWebDriver;
10 | import org.openqa.selenium.remote.service.DriverFinder;
11 |
12 | import java.net.URL;
13 | import java.util.logging.Level;
14 |
15 | public class SeleniumLoggerTest extends BaseTest {
16 | private SeleniumLogger seleniumLogger;
17 |
18 | @BeforeEach
19 | public void initialize() {
20 | seleniumLogger = new SeleniumLogger();
21 | }
22 |
23 | @Test
24 | public void defaultLogsINFO() {
25 | logsInfo();
26 |
27 | String out = "INFO Selenium [OpenTelemetry";
28 | Assertions.assertTrue(getOutput().contains(out));
29 | }
30 |
31 | @Test
32 | public void enableLogsFINE() {
33 | seleniumLogger = SeleniumLogger.enable();
34 | Assertions.assertEquals(seleniumLogger.getLevel(), Level.FINE);
35 |
36 | logsFine();
37 |
38 | String out = "FINE Selenium [SeleniumManager";
39 | Assertions.assertTrue(getOutput().contains(out));
40 | }
41 |
42 | @Test
43 | public void turnsOnAllLogs() {
44 | seleniumLogger = SeleniumLogger.all();
45 |
46 | logsMultipleClasses();
47 |
48 | Assertions.assertTrue(getOutput().contains("FINEST [HttpURLConnection"));
49 | Assertions.assertTrue(getOutput().contains("FINEST [ClientVector"));
50 | }
51 |
52 | @Test
53 | public void disableLogs() {
54 | seleniumLogger.disable();
55 |
56 | logsWarning();
57 |
58 | Assertions.assertEquals("", getOutput());
59 | }
60 |
61 | @Test
62 | public void setLevelInfoGetsWarningNotFine() {
63 | logsFine();
64 | logsWarning();
65 |
66 | String warning = "WARNING Selenium [SeleniumManager";
67 | Assertions.assertTrue(getOutput().contains(warning));
68 | String fine = "FINE Selenium [SeleniumManager";
69 | Assertions.assertFalse(getOutput().contains(fine));
70 | }
71 |
72 | @Test
73 | public void defaultFilteredClasses() {
74 | seleniumLogger.setLevel(Level.FINE);
75 | seleniumLogger.setFilter(new SeleniumFilter());
76 |
77 | logsMultipleClasses();
78 |
79 | Assertions.assertTrue(getOutput().contains("FINE Selenium [SeleniumManager"));
80 | Assertions.assertTrue(getOutput().contains("FINE Selenium [RemoteWebDriver"));
81 | Assertions.assertTrue(getOutput().contains("FINE Selenium [DriverService"));
82 | }
83 |
84 | @Test
85 | public void addToBlockedList() {
86 | seleniumLogger.setLevel(Level.FINE);
87 | SeleniumFilter filter = new SeleniumFilter();
88 | filter.addBlocked("SeleniumManager");
89 | seleniumLogger.setFilter(filter);
90 |
91 | logsMultipleClasses();
92 |
93 | Assertions.assertFalse(getOutput().contains("FINE Selenium [SeleniumManager"));
94 | Assertions.assertTrue(getOutput().contains("FINE Selenium [RemoteWebDriver"));
95 | Assertions.assertTrue(getOutput().contains("FINE Selenium [DriverService"));
96 | }
97 |
98 | @Test
99 | public void addToAllowedList() {
100 | seleniumLogger.setLevel(Level.FINE);
101 | SeleniumFilter filter = new SeleniumFilter();
102 | filter.addAllowed("http");
103 | seleniumLogger.setFilter(filter);
104 |
105 | logsMultipleClasses();
106 |
107 | Assertions.assertTrue(getOutput().contains("FINE [HttpClientImpl"));
108 | Assertions.assertTrue(getOutput().contains("FINE Selenium [SeleniumManager"));
109 | Assertions.assertTrue(getOutput().contains("FINE Selenium [DriverService"));
110 | }
111 |
112 | @Test
113 | public void addFilter() {
114 | seleniumLogger.setLevel(Level.FINE);
115 | seleniumLogger.filter("SeleniumManager");
116 |
117 | logsMultipleClasses();
118 |
119 | Assertions.assertFalse(getOutput().contains("FINE [HttpClientImpl"));
120 | Assertions.assertTrue(getOutput().contains("FINE Selenium [SeleniumManager"));
121 | Assertions.assertFalse(getOutput().contains("FINE Selenium [DriverService"));
122 | }
123 |
124 | @Test
125 | public void filtersOut() {
126 | seleniumLogger.setLevel(Level.FINE);
127 | seleniumLogger.filterOut("DriverService");
128 |
129 | logsMultipleClasses();
130 |
131 | Assertions.assertFalse(getOutput().contains("FINE [HttpClientImpl"));
132 | Assertions.assertTrue(getOutput().contains("FINE Selenium [SeleniumManager"));
133 | Assertions.assertFalse(getOutput().contains("FINE Selenium [DriverService"));
134 | }
135 |
136 | @Test
137 | public void mixAllowAndBlockLists() {
138 | seleniumLogger.setLevel(Level.FINE);
139 | SeleniumFilter filter = new SeleniumFilter();
140 | filter.addBlocked("SeleniumManager");
141 | filter.addAllowed("http");
142 | seleniumLogger.setFilter(filter);
143 |
144 | logsMultipleClasses();
145 |
146 | Assertions.assertTrue(getOutput().contains("FINE [HttpClientImpl"));
147 | Assertions.assertFalse(getOutput().contains("FINE Selenium [SeleniumManager"));
148 | Assertions.assertTrue(getOutput().contains("FINE Selenium [DriverService"));
149 | }
150 |
151 | @Test
152 | public void defaultLoggedClasses() {
153 | seleniumLogger.setLevel(Level.FINE);
154 |
155 | logsMultipleClasses();
156 |
157 | Assertions.assertTrue(getOutput().contains("FINE Selenium [SeleniumManager"));
158 | Assertions.assertTrue(getOutput().contains("FINE Selenium [RemoteWebDriver"));
159 | }
160 |
161 | @Test
162 | public void defaultFileOutput() {
163 | Assertions.assertNull(seleniumLogger.getFileOutput());
164 | }
165 |
166 | @Test
167 | public void setFileOutputDoesNotLogToConsole() {
168 | createLogFile("selenium");
169 | seleniumLogger.setFileOutput(logFile.toFile());
170 |
171 | logsWarning();
172 |
173 | Assertions.assertEquals("", getOutput());
174 | String out = "WARNING Selenium [SeleniumManager";
175 | Assertions.assertTrue(logFileContains(out));
176 | }
177 |
178 | // This is the only place Selenium uses INFO
179 | // It's a singleton, so it only works once
180 | private void logsInfo() {
181 | seleniumLogger.filter("OpenTelemetryTracer");
182 | try {
183 | URL url = new URL("http://localhost");
184 | ChromeOptions options = new ChromeOptions();
185 |
186 | new RemoteWebDriver(url, options);
187 | } catch (Throwable e) {
188 | // ignore
189 | }
190 | }
191 |
192 | private void logsFine() {
193 | try {
194 | DriverFinder.getPath(ChromeDriverService.createDefaultService(), new ChromeOptions(), false);
195 | } catch (Throwable e) {
196 | // ignore
197 | }
198 | }
199 |
200 | private void logsMultipleClasses() {
201 | ChromeOptions options = new ChromeOptions();
202 | options.addArguments("--headless=new");
203 | driver = new ChromeDriver(options);
204 | }
205 | }
206 |
--------------------------------------------------------------------------------