1 package com.atlassian.webdriver.testing.runner;
2
3 import com.atlassian.pageobjects.Defaults;
4 import com.atlassian.pageobjects.Page;
5 import com.atlassian.pageobjects.PageBinder;
6 import com.atlassian.pageobjects.ProductInstance;
7 import com.atlassian.pageobjects.TestedProduct;
8 import com.atlassian.pageobjects.TestedProductFactory;
9 import com.atlassian.pageobjects.Tester;
10 import com.atlassian.pageobjects.inject.InjectionContext;
11 import com.atlassian.webdriver.matchers.LangMatchers;
12 import com.atlassian.webdriver.testing.annotation.TestedProductClass;
13 import org.hamcrest.Matchers;
14 import org.junit.Rule;
15 import org.junit.Test;
16 import org.junit.rules.ExpectedException;
17 import org.junit.runner.notification.RunNotifier;
18 import org.junit.runners.model.InitializationError;
19
20 import javax.annotation.Nonnull;
21
22 import static com.atlassian.webdriver.matchers.ErrorMatchers.specificError;
23 import static com.atlassian.webdriver.matchers.ErrorMatchers.withCause;
24 import static com.atlassian.webdriver.matchers.ErrorMatchers.withCauses;
25 import static com.atlassian.webdriver.matchers.ErrorMatchers.withMessage;
26 import static org.hamcrest.Matchers.hasItem;
27 import static org.hamcrest.Matchers.instanceOf;
28 import static org.hamcrest.Matchers.notNullValue;
29 import static org.junit.Assert.assertThat;
30 import static org.mockito.Mockito.mock;
31
32
33
34
35
36
37 public class TestProductContextRunner
38 {
39 @Rule public ExpectedException expectedException = ExpectedException.none();
40
41 @Test
42 public void doesNotSupportTestClassesNotAnnotatedWithTestedProductClass() throws InitializationError
43 {
44 expectedException.expect(specificError(InitializationError.class, withCauses(hasItem(withMessage(
45 NotAnnotated.class.getName(),
46 "is missing the",
47 TestedProductClass.class.getName(),
48 "annotation"
49 )))));
50 new ProductContextRunner(NotAnnotated.class);
51 }
52
53 @Test
54 public void supportsOnlyProductsThatAreInjectionContexts() throws InitializationError
55 {
56 expectedException.expect(withCause(Matchers.<Throwable>allOf(LangMatchers.<Throwable>isInstance(AssertionError.class), withMessage(
57 "TestedProduct instance ",
58 MockTestedProductNotInjectionContext.class.getName(),
59 "does not support injection"
60 ))));
61 new ProductContextRunner(WithAnnotationNotInjectionContext.class).getProduct();
62 }
63
64 @Test
65 public void createsTestClassAndInjectsProductImplementingInjectionContext() throws InitializationError
66 {
67 final ProductContextRunner runner = new ProductContextRunner(WithAnnotationProductThatIsInjectionContext.class);
68 runner.run(new RunNotifier());
69 assertThat(runner.getProduct(), instanceOf(MockTestedProductThatIsInjectionContext.class));
70 MockTestedProductThatIsInjectionContext product = (MockTestedProductThatIsInjectionContext) runner.getProduct();
71 assertThat(product.injectedClass, notNullValue());
72 assertThat(product.injectedInstance, notNullValue());
73 }
74
75 @Test
76 public void supportsTestedProductClassAnnotationInSuperclasses() throws InitializationError
77 {
78 final ProductContextRunner runner = new ProductContextRunner(ExtendingCorrectlyAnnotatedClass.class);
79 runner.run(new RunNotifier());
80 assertThat(runner.getProduct(), instanceOf(MockTestedProductThatIsInjectionContext.class));
81 MockTestedProductThatIsInjectionContext product = (MockTestedProductThatIsInjectionContext) runner.getProduct();
82 assertThat(product.injectedClass, notNullValue());
83 assertThat(product.injectedInstance, notNullValue());
84 }
85
86
87
88 public static class NotAnnotated
89 {
90 @Test
91 public void satisfiesJUnit() {}
92 }
93
94 @TestedProductClass(MockTestedProductNotInjectionContext.class)
95 public static class WithAnnotationNotInjectionContext
96 {
97
98 @Test
99 public void satisfiesJUnit() {}
100 }
101
102 @TestedProductClass(MockTestedProductThatIsInjectionContext.class)
103 public static class WithAnnotationProductThatIsInjectionContext
104 {
105
106 @Test
107 public void satisfiesJUnit() {}
108 }
109
110 public static class ExtendingCorrectlyAnnotatedClass extends WithAnnotationProductThatIsInjectionContext
111 {
112
113 @Test
114 public void someOtherTest() {}
115 }
116
117 @Defaults(instanceId = "anapp", contextPath = "some-path", httpPort = 666)
118 public static class MockTestedProductNotInjectionContext implements TestedProduct<Tester>
119 {
120
121 public MockTestedProductNotInjectionContext(TestedProductFactory.TesterFactory<?> testerFactory, ProductInstance productInstance)
122 {
123 }
124
125 @Override
126 public <P extends Page> P visit(Class<P> pageClass, Object... args)
127 {
128 return null;
129 }
130
131 @Override
132 public PageBinder getPageBinder()
133 {
134 return mock(PageBinder.class);
135 }
136
137 @Override
138 public ProductInstance getProductInstance()
139 {
140 return null;
141 }
142
143 @Override
144 public Tester getTester()
145 {
146 return null;
147 }
148 }
149
150
151 @Defaults(instanceId = "anapp", contextPath = "some-path", httpPort = 666)
152 public static class MockTestedProductThatIsInjectionContext implements TestedProduct<Tester>, InjectionContext
153 {
154 public Class<?> injectedClass;
155 public Object injectedInstance;
156
157
158 public MockTestedProductThatIsInjectionContext(TestedProductFactory.TesterFactory<?> testerFactory, ProductInstance productInstance)
159 {
160 }
161
162 @Override
163 public <P extends Page> P visit(Class<P> pageClass, Object... args)
164 {
165 return null;
166 }
167
168 @Override
169 public PageBinder getPageBinder()
170 {
171 return mock(PageBinder.class);
172 }
173
174 @Override
175 public ProductInstance getProductInstance()
176 {
177 return null;
178 }
179
180 @Override
181 public Tester getTester()
182 {
183 return null;
184 }
185
186 @SuppressWarnings("ConstantConditions")
187 @Override
188 @Nonnull
189 public <T> T getInstance(@Nonnull Class<T> type)
190 {
191 return null;
192 }
193
194 @Override
195 public void injectStatic(@Nonnull Class<?> targetClass)
196 {
197 this.injectedClass = targetClass;
198 }
199
200 @Override
201 public void injectMembers(@Nonnull Object targetInstance)
202 {
203 this.injectedInstance = targetInstance;
204 }
205 }
206
207 }