When we use inner classes we get "java.lang.InstantiationException" error during element initialization
When we use inner classes we get the error during element initialization. please, look through unit test for this situation
public class NestedClassTest {
public WebDriver driver = mock(WebDriver.class);
WebElement arrow = mock(WebElement.class);
WebElement link = mock(WebElement.class);
@Before
public void before() {
when(driver.findElement(By.className("arrow"))).thenReturn(arrow);
when(arrow.findElement(By.className("link"))).thenReturn(link);
}
@Test
public void test() {
NestedPageObject pageObject = new NestedPageObject();
HtmlElementLoader.populate(pageObject, driver);
assertThat(pageObject, notNullValue());
assertThat(pageObject.arrow.getName(), notNullValue());
assertThat(pageObject.arrow.link.getWrappedElement(), notNullValue());
}
public class NestedPageObject {
@FindBy(className = "arrow")
public NestedHtmlElement arrow;
}
public class NestedHtmlElement extends HtmlElement {
@FindBy(className = "link")
public NestedTypifiedElement link;
public class NestedTypifiedElement extends TypifiedElement {
public NestedTypifiedElement(WebElement wrappedElement) {
super(wrappedElement);
}
}
}
}
Trace
ru.yandex.qatools.htmlelements.exceptions.HtmlElementsException: java.lang.InstantiationException: ru.yandex.qatools.htmlelements.NestedClassTest$NestedHtmlElement
at ru.yandex.qatools.htmlelements.loader.decorator.HtmlElementFactory.createTypifiedElementInstance(HtmlElementFactory.java:53)
at ru.yandex.qatools.htmlelements.loader.decorator.HtmlElementDecorator.decorateTypifiedElement(HtmlElementDecorator.java:102)
at ru.yandex.qatools.htmlelements.loader.decorator.HtmlElementDecorator.decorate(HtmlElementDecorator.java:66)
at org.openqa.selenium.support.PageFactory.proxyFields(PageFactory.java:115)
at org.openqa.selenium.support.PageFactory.initElements(PageFactory.java:107)
at ru.yandex.qatools.htmlelements.loader.decorator.HtmlElementDecorator.decorateHtmlElement(HtmlElementDecorator.java:115)
at ru.yandex.qatools.htmlelements.loader.decorator.HtmlElementDecorator.decorate(HtmlElementDecorator.java:70)
at org.openqa.selenium.support.PageFactory.proxyFields(PageFactory.java:115)
at org.openqa.selenium.support.PageFactory.initElements(PageFactory.java:107)
at ru.yandex.qatools.htmlelements.loader.HtmlElementLoader.populatePageObject(HtmlElementLoader.java:200)
at ru.yandex.qatools.htmlelements.loader.HtmlElementLoader.populatePageObject(HtmlElementLoader.java:190)
at ru.yandex.qatools.htmlelements.loader.HtmlElementLoader.populate(HtmlElementLoader.java:58)
at ru.yandex.qatools.htmlelements.NestedClassTest.test(NestedClassTest.java:36)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
at org.junit.runner.JUnitCore.run(JUnitCore.java:160)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:78)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:212)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:68)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:140)
Caused by: java.lang.InstantiationException: ru.yandex.qatools.htmlelements.NestedClassTest$NestedHtmlElement
at java.lang.Class.newInstance(Class.java:427)
at ru.yandex.qatools.htmlelements.utils.HtmlElementUtils.newInstance(HtmlElementUtils.java:35)
at ru.yandex.qatools.htmlelements.loader.decorator.HtmlElementFactory.createTypifiedElementInstance(HtmlElementFactory.java:49)
... 39 more
Caused by: java.lang.NoSuchMethodException: ru.yandex.qatools.htmlelements.NestedClassTest$NestedHtmlElement.<init>()
at java.lang.Class.getConstructor0(Class.java:3082)
at java.lang.Class.newInstance(Class.java:412)
... 41 more
I guess problem in this
Hi, thank you for bug report and investigation, but it looks like you create problems for yourself =). Using nested Page Object in tests is a bad practice since you don't have a single point to view/fix your application presentation part. Using nested classes limits code reuse as well. So, what's the point in using nested Page Objects and nested elements declaration?
update this version ru.yandex.qatools.htmlelements to 1.20.0, in earlier version it was using newInstance() method which is deprecated now. I hope this will solve the issue.