diff --git a/bb-eyes/pom.xml b/bb-eyes/pom.xml
new file mode 100644
index 00000000..18d337e9
--- /dev/null
+++ b/bb-eyes/pom.xml
@@ -0,0 +1,57 @@
+
+
+ 4.0.0
+
+
+ bobcat
+ com.cognifide.qa.bb
+ 1.4.1-SNAPSHOT
+
+
+ bb-eyes
+ Bobcat Eyes
+
+
+
+ com.google.inject
+ guice
+
+
+
+ org.slf4j
+ slf4j-api
+
+
+ junit
+ junit
+
+
+ com.applitools
+ eyes-selenium-java3
+ RELEASE
+
+
+ io.appium
+ java-client
+
+
+
+
+ com.cognifide.qa.bb
+ bb-core
+ ${project.version}
+
+
+
+
+
+
+ org.apache.rat
+ apache-rat-plugin
+
+
+
+
+
diff --git a/bb-eyes/src/main/java/com/cognifide/qa/bb/eyes/EyesModule.java b/bb-eyes/src/main/java/com/cognifide/qa/bb/eyes/EyesModule.java
new file mode 100644
index 00000000..54fd55ff
--- /dev/null
+++ b/bb-eyes/src/main/java/com/cognifide/qa/bb/eyes/EyesModule.java
@@ -0,0 +1,31 @@
+/*-
+ * #%L
+ * Bobcat
+ * %%
+ * Copyright (C) 2016 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;
+
+import com.applitools.eyes.selenium.Eyes;
+import com.google.inject.AbstractModule;
+
+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/EyesProvider.java b/bb-eyes/src/main/java/com/cognifide/qa/bb/eyes/EyesProvider.java
new file mode 100644
index 00000000..92af7244
--- /dev/null
+++ b/bb-eyes/src/main/java/com/cognifide/qa/bb/eyes/EyesProvider.java
@@ -0,0 +1,36 @@
+package com.cognifide.qa.bb.eyes;
+
+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;
+
+@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/WithEyes.java b/bb-eyes/src/main/java/com/cognifide/qa/bb/eyes/WithEyes.java
new file mode 100644
index 00000000..6c3ec874
--- /dev/null
+++ b/bb-eyes/src/main/java/com/cognifide/qa/bb/eyes/WithEyes.java
@@ -0,0 +1,57 @@
+package com.cognifide.qa.bb.eyes;
+
+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;
+
+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;
+ }
+
+ public WebDriver getWebDriver() {
+ return webDriver;
+ }
+
+ public Eyes getEyes() {
+ return eyes;
+ }
+
+ @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/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: ''