Skip to content

Commit

Permalink
bring harmony between custom system configurations and selenide's
Browse files Browse the repository at this point in the history
  • Loading branch information
sergiomartins8 committed Apr 18, 2020
1 parent f2455d1 commit b38868c
Show file tree
Hide file tree
Showing 14 changed files with 83 additions and 92 deletions.
27 changes: 17 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,26 +61,33 @@ $ mvn test [-Dselenide.remote=http://localhost:4444/wd/hub]
#### System properties

````shell script
$ mvn test [-Dmock.server.url=<url> -Dmock.server.port=<port>] [-Dparallel=<method>] [-DthreadCount=<n>] [-Dlistener=<listener1, listener2, ...>]
$ mvn test [-Dmock.server.url=<url> -Dmock.server.port=<port>] \
[-Dparallel=<method>] \
[-DthreadCount=<n>] \
[-Dlistener=<listener1, listener2, ...>]
````

| Property | Description | Default |
| --------------------------------- | --------------------------------- | ----------------------------------------- |
| `mock.server.url` | Mock server url. | `null` _(Mock server it not used)_ |
| `mock.server.port` | Mock server port. | `0` _(Mock server it not used)_ |
| `parallel` | Enables parallel threads. | `false` |
| `threadCount` | The default number of threads to use when running tests in parallel. | `1` |
| `listener` | A comma-separated list of java classes that can be found on your classpath. | `null` _(Listeners not being used)_ |
| Property | Description | Default |
| --------------------------------- | --------------------------------- | ----------------------------------------- |
| `mock.server.address` | Mock server address | `null` _(Mock server it not used)_ |
| `parallel` | Enables parallel threads | `false` |
| `threadCount` | The default number of threads to use when running tests in parallel | `1` |
| `listener` | A comma-separated list of java classes that can be found on your classpath | `null` _(Listeners not being used)_ |

#### More system properties

Using the goods of selenide, you can also inject its system properties
Using the goods of selenide, you can also inject its system properties.

##### Example:
```shell script
mvn test -Dselenide.remote=http://localhost:4444/wd/hub -Dselenide.headless=true -Dselenide.browser=firefox -Dselenide.baseUrl=http:/google.com
mvn test -Dselenide.remote=http://localhost:4444/wd/hub \
-Dselenide.headless=true \
-Dselenide.browser=firefox \
-Dselenide.baseUrl=http:/google.com
```

More about selenide's configuration settings and documentation [here](https://selenide.org/javadoc/current/com/codeborne/selenide/Configuration.html).

### Listeners

There are a couple listeners available _(however, disabled by default)_.
Expand Down
27 changes: 15 additions & 12 deletions src/test/java/base/FrameworkBootstrap.java
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
package base;

import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.AfterSuite;
import org.testng.annotations.BeforeSuite;
import utils.config.CustomConfiguration;
import utils.logging.Loggable;

import java.util.Optional;

/**
* Where it all starts.
* <br>
Expand All @@ -13,22 +16,22 @@
public abstract class FrameworkBootstrap implements Loggable {

/**
* Use {@code @BeforeMethod} when running tests in {@code parallel=methods}. Edit accordingly.
* If sequential test execution use {@code @BeforeSuite} annotation.
* Tells {@link MockContext} to initialize the mock server if it is present as a system property.
*/
@BeforeMethod
@BeforeSuite
public void initializeMockServer() {
MockContext.initializeMockServerClient();
if (Optional.ofNullable(CustomConfiguration.mockServerAddress).isPresent()) {
MockContext.initializeMockServerClient();
}
}

/**
* Related to the {@link #initializeMockServer()} method.
* <br>
* Use {@code @AfterMethod} when running tests in {@code parallel=methods}. Edit accordingly.
* If sequential test execution use {@code @AfterSuite} annotation.
* Tells {@link MockContext} to reset the mock server data if it is present as a system property.
*/
@AfterMethod
@AfterSuite
public void teardownMockServer() {
MockContext.resetMockServerClient();
if (Optional.ofNullable(CustomConfiguration.mockServerAddress).isPresent()) {
MockContext.resetMockServerClient();
}
}
}
48 changes: 14 additions & 34 deletions src/test/java/base/MockContext.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,50 +2,30 @@

import org.mockserver.client.MockServerClient;
import utils.config.CustomConfiguration;
import utils.listeners.MockServerListener;

import java.net.URI;

/**
* Single responsibility is to hold a mock server object so that it can be used by the {@link MockServerListener}.
* Context for objects for mocking purposes.
*/
public final class MockContext {

/**
* Thread safe implementation that holds the mock server client.
*/
private static final ThreadLocal<MockServerClient> MOCK_SERVER_CLIENT_THREAD_LOCAL = new ThreadLocal<>();

/**
* Verifies if both mock server url and port are set as system properties.
* <br>
* System properties may be set as such:
* <br>
* Example: {@code mvn clean test -Dmock.server.url=localhost -Dmock.server.port=3000}
* <br>
* However, system properties can also be configured under testng.xml configuration
*/
public static final boolean HAS_MOCK_SERVER_PROPERTY = CustomConfiguration.mockServerUrl != null
&& CustomConfiguration.mockServerPort != 0;
public class MockContext {

public static MockServerClient getMockServerClient() {
return MOCK_SERVER_CLIENT_THREAD_LOCAL.get();
}
private static MockServerClient mockServerClient;

/**
* Initializes the mock server client if {@link #HAS_MOCK_SERVER_PROPERTY} is true.
* Initializes the mock server client based on {@link CustomConfiguration} settings.
*/
public static void initializeMockServerClient() {
if (HAS_MOCK_SERVER_PROPERTY) {
MockServerClient mockServerClient = new MockServerClient(CustomConfiguration.mockServerUrl, CustomConfiguration.mockServerPort);
MOCK_SERVER_CLIENT_THREAD_LOCAL.set(mockServerClient);
}
MockContext.mockServerClient = new MockServerClient(
URI.create(CustomConfiguration.mockServerAddress).getHost(),
URI.create(CustomConfiguration.mockServerAddress).getPort());
}

/**
* Resets the mock server client if {@link #HAS_MOCK_SERVER_PROPERTY} is true.
*/
public static void resetMockServerClient() {
if (HAS_MOCK_SERVER_PROPERTY) {
MOCK_SERVER_CLIENT_THREAD_LOCAL.get().reset();
}
mockServerClient.reset();
}

public static MockServerClient getMockServerClient() {
return mockServerClient;
}
}
2 changes: 1 addition & 1 deletion src/test/java/pageobjects/selectors/ExampleSelector.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package pageobjects.selectors;

public final class ExampleSelector {
public class ExampleSelector {

/**
* Private constructor to avoid instantiation.
Expand Down
2 changes: 1 addition & 1 deletion src/test/java/tests/ExampleTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ public void teardown() {

@Test(description = "Open up a google page and search for the word 'dogs'")
public void testExampleOne() {
open(""); // empty string opens the base URL defined on <config.${environment}.properties>
open("http://google.com");

examplePage.exampleComponent()
.waitPageLoaded()
Expand Down
12 changes: 2 additions & 10 deletions src/test/java/utils/config/CustomConfiguration.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,17 +17,9 @@ public class CustomConfiguration {

/**
* URL for the mock server.
* Can be configured either programmatically or by system property: {@code -Dmock.server.url=localhost}
* Can be configured either programmatically or by system property: {@code -Dmock.server.address=localhost:3000}
* <br>
* Default value: null (Mock server it not used)
*/
public static String mockServerUrl = DEFAULTS.mockServerUrl();

/**
* Port for the mock server.
* Can be configured either programmatically or by system property: {@code -Dmock.server.port=3000}
* <br>
* Default value: 0 (Mock server it not used)
*/
public static int mockServerPort = DEFAULTS.mockServerPort();
public static String mockServerAddress = DEFAULTS.mockServerAddress();
}
14 changes: 6 additions & 8 deletions src/test/java/utils/config/CustomConfigurationHolder.java
Original file line number Diff line number Diff line change
@@ -1,15 +1,13 @@
package utils.config;

public class CustomConfigurationHolder {
import utils.logging.Loggable;

private final String mockServerUrl = System.getProperty("mock.server.url");
private final int mockServerPort = Integer.parseInt(System.getProperty("mock.server.port", "0"));
public class CustomConfigurationHolder implements Loggable {

public String mockServerUrl() {
return mockServerUrl;
}
private final String mockServerAddress = System.getProperty("mock.server.address");

public int mockServerPort() {
return mockServerPort;
public String mockServerAddress() {
logger().debug("Mock server address: " + mockServerAddress);
return mockServerAddress;
}
}
2 changes: 2 additions & 0 deletions src/test/java/utils/listeners/MockServerListener.java
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,9 @@ public class MockServerListener implements ITestListener, Loggable {
public void onTestStart(ITestResult result) {
extractMockAnnotation(result).ifPresent(mock -> {
for (String path : mock.path()) {
logger().debug("Mocking file on path: " + path);
MockDefinition mockDefinition = MockParser.toObject(path);
logger().debug("Mocking content: " + mockDefinition.prettyPrint());
MockContext.getMockServerClient()
.when(request()
.withMethod(requireNonNull(mockDefinition).getRequest().getMethod())
Expand Down
15 changes: 12 additions & 3 deletions src/test/java/utils/mocks/MockDefinition.java
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
package utils.mocks;

import com.google.gson.GsonBuilder;
import utils.mocks.model.MockRequest;
import utils.mocks.model.MockResponse;

/**
* Concrete definition of a mock.
* <p>
* <br>
* A mock is represented by a {@link MockRequest} and by a {@link MockResponse}
* </p>
*/
@SuppressWarnings("unused")
public final class MockDefinition {
public class MockDefinition {

/**
* Represents the mocked request.
Expand All @@ -37,4 +37,13 @@ public void setResponse(MockResponse response) {
public void setRequest(MockRequest request) {
this.request = request;
}

/**
* Similar to a `toString()` implementation. Useful for debugging purposes.
*
* @return current object in a pretty json format.
*/
public String prettyPrint() {
return new GsonBuilder().setPrettyPrinting().create().toJson(this);
}
}
2 changes: 1 addition & 1 deletion src/test/java/utils/mocks/MockParser.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
/**
* Single responsibility of parsing json files into {@link MockDefinition} objects.
*/
public final class MockParser {
public class MockParser {

public static MockDefinition toObject(String jsonPath) {
return new Gson().fromJson(new InputStreamReader(MockParser.class.getResourceAsStream(jsonPath)), MockDefinition.class);
Expand Down
2 changes: 1 addition & 1 deletion src/test/java/utils/mocks/model/MockHeader.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
* Concrete definition of a mocked header.
*/
@SuppressWarnings("unused")
public final class MockHeader {
public class MockHeader {

private String name;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
* Concrete definition of a mocked query parameter.
*/
@SuppressWarnings("unused")
public final class MockQueryStringParameter {
public class MockQueryStringParameter {

private String name;

Expand Down
2 changes: 1 addition & 1 deletion src/test/java/utils/mocks/model/MockRequest.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
* Each header is represented by {@link MockHeader}
*/
@SuppressWarnings("unused")
public final class MockRequest {
public class MockRequest {

private String path;

Expand Down
18 changes: 9 additions & 9 deletions src/test/java/utils/mocks/model/MockResponse.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,17 @@

/**
* Concrete definition of a mocked response.
*
* <p>A mocked response is represented by a body and a status code.
*
* <p>Optionally, it also may contain a list of headers and a list of cookies.
*
* <p>Each header is represented by {@link MockHeader}
*
* <p>Each cookie is represented by {@link MockCookie}
* <br>
* A mocked response is represented by a body and a status code.
* <br>
* Optionally, it also may contain a list of headers and a list of cookies.
* <br>
* Each header is represented by {@link MockHeader}
* <br>
* Each cookie is represented by {@link MockCookie}
*/
@SuppressWarnings("unused")
public final class MockResponse {
public class MockResponse {

/**
* Holds the whole response body.
Expand Down

0 comments on commit b38868c

Please sign in to comment.