diff --git a/bb-eyes/pom.xml b/bb-eyes/pom.xml new file mode 100644 index 00000000..3119baa1 --- /dev/null +++ b/bb-eyes/pom.xml @@ -0,0 +1,86 @@ + + + + 4.0.0 + + + bobcat + com.cognifide.qa.bb + 1.5.1-SNAPSHOT + + + bb-eyes + Bobcat Eyes + + + + com.google.inject + guice + + + + org.slf4j + slf4j-api + + + junit + junit + + + org.junit.jupiter + junit-jupiter-api + + + com.applitools + eyes-selenium-java3 + RELEASE + + + io.appium + java-client + + + + + + com.cognifide.qa.bb + bb-core + ${project.version} + + + com.cognifide.qa.bb + bb-junit5 + ${project.version} + + + + + + + org.apache.rat + apache-rat-plugin + + + + + diff --git a/bb-eyes/src/main/java/com/cognifide/qa/bb/eyes/guice/EyesModule.java b/bb-eyes/src/main/java/com/cognifide/qa/bb/eyes/guice/EyesModule.java new file mode 100644 index 00000000..d013b7ed --- /dev/null +++ b/bb-eyes/src/main/java/com/cognifide/qa/bb/eyes/guice/EyesModule.java @@ -0,0 +1,34 @@ +/*- + * #%L + * Bobcat + * %% + * Copyright (C) 2018 Cognifide Ltd. + * %% + * 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. + * #L% + */ +package com.cognifide.qa.bb.eyes.guice; + +import com.applitools.eyes.selenium.Eyes; +import com.google.inject.AbstractModule; + +/** + * Eyes Guice module. Provides an {@link Eyes} instance. + */ +public class EyesModule extends AbstractModule { + + @Override + protected void configure() { + bind(Eyes.class).toProvider(EyesProvider.class); + } +} diff --git a/bb-eyes/src/main/java/com/cognifide/qa/bb/eyes/guice/EyesProvider.java b/bb-eyes/src/main/java/com/cognifide/qa/bb/eyes/guice/EyesProvider.java new file mode 100644 index 00000000..897bb01d --- /dev/null +++ b/bb-eyes/src/main/java/com/cognifide/qa/bb/eyes/guice/EyesProvider.java @@ -0,0 +1,65 @@ +/*- + * #%L + * Bobcat + * %% + * Copyright (C) 2018 Cognifide Ltd. + * %% + * 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. + * #L% + */ +package com.cognifide.qa.bb.eyes.guice; + +import com.applitools.eyes.selenium.Eyes; +import com.cognifide.qa.bb.guice.ThreadScoped; +import com.google.inject.Inject; +import com.google.inject.Provider; +import com.google.inject.name.Named; + +/** + * Provides a thread-scoped {@link Eyes} instance. Bound in {@link EyesModule}. + *
+ * Requires {@code eyes.apiKey} property. + *
+ * Additional configurable options: + * + */ +@ThreadScoped +public class EyesProvider implements Provider { + + private Eyes cachedEyes; + + @Inject + @Named("eyes.apiKey") + private String apiKey; + + @Inject + @Named("eyes.fullPageScreenshots") + private boolean fullPageScreenshots; + + @Override + public Eyes get() { + if (cachedEyes == null) { + cachedEyes = create(); + } + return cachedEyes; + } + + private Eyes create() { + Eyes eyes = new Eyes(); + eyes.setApiKey(apiKey); + eyes.setForceFullPageScreenshot(fullPageScreenshots); + return eyes; + } +} diff --git a/bb-eyes/src/main/java/com/cognifide/qa/bb/eyes/junit4/WithEyes.java b/bb-eyes/src/main/java/com/cognifide/qa/bb/eyes/junit4/WithEyes.java new file mode 100644 index 00000000..aae80496 --- /dev/null +++ b/bb-eyes/src/main/java/com/cognifide/qa/bb/eyes/junit4/WithEyes.java @@ -0,0 +1,102 @@ +/*- + * #%L + * Bobcat + * %% + * Copyright (C) 2018 Cognifide Ltd. + * %% + * 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. + * #L% + */ +package com.cognifide.qa.bb.eyes.junit4; + +import org.junit.rules.TestRule; +import org.junit.runner.Description; +import org.junit.runners.model.Statement; +import org.openqa.selenium.WebDriver; +import org.openqa.selenium.support.events.EventFiringWebDriver; + +import com.applitools.eyes.selenium.Eyes; +import com.google.inject.Inject; +import com.google.inject.name.Named; + +/** + * JUnit 4 {@link TestRule} that enables Eyes integration. + *

+ * Example usage: + *

+ * public class ExampleTest {
+ *    @Rule
+ *    @Inject
+ *    public WithEyes withEyes;
+ *
+ *    public void test() {
+ *      // test actions
+ *      withEyes.getEyes().checkWindow("Example checkpoint");
+ *    }
+ * }
+ * 
+ */ +public class WithEyes implements TestRule { + + private final WebDriver webDriver; + private final Eyes eyes; + private String appName; + + @Inject + public WithEyes(WebDriver webDriver, Eyes eyes, @Named("eyes.appName") String appName) { + this.webDriver = webDriver; + this.eyes = eyes; + this.appName = appName; + } + + /** + * @return the avaialable WebDriver instance + */ + public WebDriver getWebDriver() { + return webDriver; + } + + /** + * @return the configured and initialized {@link Eyes} instance. + */ + public Eyes getEyes() { + return eyes; + } + + /** + * {@inheritDoc} + */ + @Override + public Statement apply(Statement base, Description description) { + return new Statement() { + @Override + public void evaluate() throws Throwable { + try { + WebDriver wrappedDriver = ((EventFiringWebDriver) webDriver).getWrappedDriver(); + eyes.open(wrappedDriver, appName, description.getMethodName()); + base.evaluate(); + } finally { + closeEyes(); + } + } + }; + } + + private void closeEyes() { + try { + eyes.close(); + } finally { + eyes.abortIfNotClosed(); + } + } +} diff --git a/bb-eyes/src/main/java/com/cognifide/qa/bb/eyes/junit5/WithEyes.java b/bb-eyes/src/main/java/com/cognifide/qa/bb/eyes/junit5/WithEyes.java new file mode 100644 index 00000000..b898bab4 --- /dev/null +++ b/bb-eyes/src/main/java/com/cognifide/qa/bb/eyes/junit5/WithEyes.java @@ -0,0 +1,36 @@ +/*- + * #%L + * Bobcat + * %% + * Copyright (C) 2018 Cognifide Ltd. + * %% + * 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. + * #L% + */ +package com.cognifide.qa.bb.eyes.junit5; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +import org.junit.jupiter.api.extension.ExtendWith; + +/** + * Meta-annotation enabling the {@link WithEyesExtension}. + */ +@Target({ElementType.ANNOTATION_TYPE, ElementType.METHOD, ElementType.TYPE}) +@Retention(RetentionPolicy.RUNTIME) +@ExtendWith(WithEyesExtension.class) +public @interface WithEyes { +} diff --git a/bb-eyes/src/main/java/com/cognifide/qa/bb/eyes/junit5/WithEyesExtension.java b/bb-eyes/src/main/java/com/cognifide/qa/bb/eyes/junit5/WithEyesExtension.java new file mode 100644 index 00000000..bb0fe7fa --- /dev/null +++ b/bb-eyes/src/main/java/com/cognifide/qa/bb/eyes/junit5/WithEyesExtension.java @@ -0,0 +1,73 @@ +/*- + * #%L + * Bobcat + * %% + * Copyright (C) 2018 Cognifide Ltd. + * %% + * 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. + * #L% + */ +package com.cognifide.qa.bb.eyes.junit5; + +import static com.cognifide.qa.bb.junit5.JUnit5Constants.NAMESPACE; + +import java.util.Properties; + +import org.junit.jupiter.api.extension.AfterEachCallback; +import org.junit.jupiter.api.extension.BeforeEachCallback; +import org.junit.jupiter.api.extension.ExtensionContext; +import org.openqa.selenium.WebDriver; +import org.openqa.selenium.support.events.EventFiringWebDriver; + +import com.applitools.eyes.selenium.Eyes; +import com.cognifide.qa.bb.junit5.guice.InjectorUtils; +import com.google.inject.Injector; +import com.google.inject.Key; + +/** + * JUnit 5 extension that provides {@link Eyes} capabilities. + */ +public class WithEyesExtension implements BeforeEachCallback, AfterEachCallback { + + /** + * Opens an {@link Eyes} session before the test. + *
+ * {@inheritDoc} + */ + @Override + public void beforeEach(ExtensionContext context) throws Exception { + Injector injector = InjectorUtils.retrieveInjectorFromStore(context, NAMESPACE); + Properties properties = injector.getInstance(Key.get(Properties.class)); + WebDriver wrappedDriver = ((EventFiringWebDriver) injector.getInstance(WebDriver.class)).getWrappedDriver(); + getEyes(context).open(wrappedDriver, String.valueOf(properties.get("eyes.appName")), context.getDisplayName()); + } + + /** + * Closes or aborts the opened {@link Eyes} session. + *
+ * {@inheritDoc} + */ + @Override + public void afterEach(ExtensionContext context) throws Exception { + Eyes eyes = getEyes(context); + try { + eyes.close(); + } finally { + eyes.abortIfNotClosed(); + } + } + + private Eyes getEyes(ExtensionContext context) { + return InjectorUtils.retrieveInjectorFromStore(context, NAMESPACE).getInstance(Eyes.class); + } +} diff --git a/bb-eyes/src/main/resources/config.yaml b/bb-eyes/src/main/resources/config.yaml new file mode 100644 index 00000000..afbf8c3b --- /dev/null +++ b/bb-eyes/src/main/resources/config.yaml @@ -0,0 +1,5 @@ +default: + properties: + eyes.apiKey: '' + eyes.fullPageScreenshots: true + eyes.appName: ''