I'm using POM in my selenium automation project, so there is an abstract class BasePage extended by a DerivedPage which is used for test method
The method which returns Webdriver works before aop was applied, but keeps returning null after aspect annotation.
From my view, spring aop proxy wrapped the primal instance of DerivedPage, which already init the Webdriver, and overwrite getDriver to get it. But it doesn't work as expected.
I know there are two inheritance: BasePage -> DerivedPage -> AOP Proxy, but can't figure out why it can't get the @Autowired object.
Example Basepage
@Component
@Scope("cucumber-glue")
public abstract class BasePage {
@Autowired protected WebDriver driver;
@PostConstruct
private void postConstruct() {
PageFactory.initElements(driver, this);
}
//driver found after remove this aspect annotation
@TakeScreenshot
public WebDriver getDriver() {
return driver;
}
Example DerivedPage
@Component
@Scope("cucumber-glue")
public class DerivedPage extends BasePage {
@FindBy(css = "a[href*=\"member\"]#custom-btn")
public WebElement memberButton;
}
Example Aspect Class
@Aspect
@Component
public class ScreenshotAspect {
@Around("@annotation(TakeScreenshot)")
public void take(){
ScreenshotUtil.doCaptureFullScreen();
}
}
Example Test Method
public class SampleSteps {
@Autowired
private DerivedPage derivedPage;
@Test
public void test() {
System.out.println(derivedPage.getDriver()); //returns null, but screenshot was taken
}
}
Here I posted a simple MCVE project to reproduce the issue https://github.com/Cordifhyura/Spring-AOP-issue
result:
Testing started at 14:10 ...
SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v2.6.6)
Starting ChromeDriver 100.0.4896.60 (6a5d10861ce8de5fce22564658033b43cb7de047-refs/branch-heads/4896@{#875}) on port 40627
Only local connections are allowed.
Please see https://chromedriver.chromium.org/security-considerations for suggestions on keeping ChromeDriver safe.
ChromeDriver was started successfully.
[2022-04-28 14:10:48.832] - 31332 INFO [Forwarding newSession on session null to remote] --- org.openqa.selenium.remote.ProtocolHandshake: Detected dialect: W3C
Starting - enter holo homepage and click member
ChromeDriver: chrome on WINDOWS (898dda5b1132c26741c8f8db732c1dc1) **//direct Webdriver reference in Hooks**
base.PO.HoloPage$$EnhancerBySpringCGLIB$$1308317
simulate screen capture
null **//.getDriver() in pageobject**
1 Scenarios (1 passed)
1 Steps (1 passed)
0m4.255s
As you can see the driver is correctly injected to Hook, so it's nothing with the DI or cucumber. It just missing in the AOP proxy instance.
The ScreenshotAspect is incorrect.
The @Around
advice should have a valid proceed()
as explained in the documenation section : Around Advice
Do read through the information section starting with "If you declare the return type of your around advice method as void, null will always be returned to the caller,.." as well to understand what could have caused the null value to be returned.