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