/*******************************************************************************
* Copyright 2017 Ivan Shubin http://galenframework.com
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
******************************************************************************/
package com.galenframework.support;
import com.galenframework.api.Galen;
import com.galenframework.reports.GalenTestInfo;
import com.galenframework.reports.TestReport;
import com.galenframework.reports.model.LayoutReport;
import com.galenframework.speclang2.pagespec.SectionFilter;
import com.galenframework.utils.GalenUtils;
import org.openqa.selenium.Dimension;
import org.openqa.selenium.WebDriver;
import java.io.IOException;
import java.lang.reflect.Method;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Properties;
/**
* This class is used as a base test class for Java tests tests.
* It takes care of storing WebDriver and Report instances in {@link ThreadLocal} so that the tests could be run in parallel
* without any race condition. It also quits the WebDriver at the end of the test.
* It has {@link #checkLayout} method which als takes care of storing the layout report in reports container.
*/
public abstract class GalenJavaTestBase {
protected ThreadLocal<WebDriver> driver = new ThreadLocal<>();
protected ThreadLocal<TestReport> report = new ThreadLocal<>();
protected ThreadLocal<GalenTestInfo> testInfo = new ThreadLocal<>();
/**
* Returns the report for current test thread
*
* @return the instance of TestReport for current thread
*/
public TestReport getReport() {
TestReport report = this.report.get();
if (report == null) {
throw new RuntimeException("The report is not instantiated yet");
}
return report;
}
public GalenTestInfo createTestInfo(Method method, Object[] arguments) {
return GalenTestInfo.fromMethod(method, arguments);
}
/**
* Loads the given url in the current driver for current test thread
*
* @param url The website url that should be loaded in the current driver
*/
public void load(String url) {
getDriver().get(url);
}
/**
* Loads the given url in the current driver for current test thread and changes the browser window size
*
* @param url The website url that should be loaded in the current driver
* @param width The width of browser window
* @param height The height of browser window
*/
public void load(String url, int width, int height) {
load(url);
resize(width, height);
}
/**
* Injects the given javaScript expression in current driver for current test thread
*
* @param javaScript A JavaScript code that should be executed in the current browser
*/
public void inject(String javaScript) {
GalenUtils.injectJavascript(getDriver(), javaScript);
}
/**
* Changes the size of current browser for current test thread
*
* @param width The width of browser window
* @param height The height of browser window
*/
public void resize(int width, int height) {
getDriver().manage().window().setSize(new Dimension(width, height));
}
/**
* Checks layout of the page that is currently open in current thread. Takes driver from {@link ThreadLocal}
*
* @param specPath a path to galen spec file
* @param includedTags a list of tags that should be included in spec
* @throws IOException
*/
public void checkLayout(String specPath, List<String> includedTags) throws IOException {
checkLayout(specPath, new SectionFilter(includedTags, Collections.<String>emptyList()), new Properties(), null);
}
/**
* Checks layout of the page that is currently open in current thread. Takes driver from ThreadLocal
*
* @param specPath a path to galen spec file
* @param sectionFilter a filter that is used for "@on" filtering in specs
* @param properties a set of properties that will be accessible in special galen spec expressions.
* @param vars JavaScript variables that will be available in special galen spec expressions
* @throws IOException
*/
public void checkLayout(String specPath, SectionFilter sectionFilter, Properties properties, Map<String, Object> vars) throws IOException {
String title = "Check layout " + specPath;
LayoutReport layoutReport = Galen.checkLayout(getDriver(), specPath, sectionFilter, properties, vars);
getReport().layout(layoutReport, title);
if (layoutReport.errors() > 0) {
throw new LayoutValidationException(specPath, layoutReport, sectionFilter);
}
}
/**
* Initializes the WebDriver instance and stores it in {@link ThreadLocal}
*
* @param args the arguments of current test
*/
public void initDriver(Object[] args) {
WebDriver driver = createDriver(args);
this.driver.set(driver);
}
/**
* Used in order to initialize a {@link WebDriver}
*
* @param args the arguments of current test
* @return
*/
public abstract WebDriver createDriver(Object[] args);
public void quitDriver() {
getDriver().quit();
}
/**
* Returns {@link WebDriver} instance for current test thread
*
* @return a {@link WebDriver} instance for current test thread
*/
public WebDriver getDriver() {
WebDriver driver = this.driver.get();
if (driver == null) {
throw new RuntimeException("The driver is not instantiated yet");
}
return driver;
}
}