I have two different aspects in my Selenium test automation project and I am using load time weaving with AspectJ. Both aspects run fine when running under test methods in that class.
The case where AspectA
running on @Before("@annotation(ChangeToIFrameA)")
on a method1
that is under a method0
that is already annotated with @Before
class it overrides the second aspect call AspectB
on method2
that is called under method1
.
Aspect A class
package com.stackoverfow.FrameHandling;
@Aspect
public class AspectA {
@Before("@annotation(com.stackoverfow.FrameHandling.ChangeToIFrameA)")
public void switchIFrameA(WebDriver driver)) {
driver.switchTo().frame("IFrameA name");
}
}
Custom Annotated class for Aspect A to run
package com.stackoverfow.FrameHandling;
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface ChangeToIFrameA {
}
Aspect B class
package com.stackoverfow.FrameHandling;
@Aspect
public class AspectB {
@Before("execution(com.stackoverfow.NavigationBar.*(..))")
public void switchIFrameB(WebDriver driver)) {
driver.switchTo().frame("IFrameB name");
}
@After("execution(com.stackoverfow.NavigationBar.*(..))")
public void switchIFrameA(WebDriver driver)) {
driver.switchTo().frame("IFrameA name");
}
}
Navigation Bar Class
package com.stackoverfow.Navigation;
class NavigationBar{
class NavigationBar(){}
public void goToHomePage(){
//Navigates to Home Page
}
public void goToHelpPage(){
//Navigates to Help Page
}
public void goToUserAccount(){
//Navigates to User Account Page
}
}
Test Class that uses TestNG
package com.stackoverfow.NavigationTests;
public class AppBasicTests {
@BeforeClass(alwaysRun = true)
public void login(ITestContext context) {
//logs into the application
takeCareOfNavigationToHomePage();
}
@BeforeMethod(alwaysRun = true)
public void openSecondTab(ITestContext context) {
//Open a new tab
}
@AfterMethod(alwaysRun = true)
public void closeSecondTab() {
//closes the secondary tab
}
@AfterClass(alwaysRun = true)
public void logout() {
//logs out from the app
}
//Annotated to private method that is called inside login() method which is annotated by @Before class
@ChangeToIFrameA
private void takeCareOfNavigationToHomePage(){
NavigationBar navigationBar = new NavigationBar();
navigationBar.goToHomePage();// Assuming AspectB runs before and after this method call for switching frames
}
//Assuming it switches to FrameA before running the test
@ChangeToIFrameA
@Test(enabled = true)
public void testNavigation(){
NavigationBar navigationBar = new NavigationBar();
navigationBar.goToHelpPage();// Assuming AspectB runs
before and after this method call for switching frames
}
}
aop.xml
<?xml version="1.0" encoding="UTF-8"?>
<aspectj>
<aspects>
<aspect name="com.stackoverfow.FrameHandling.AspectA"/>
</aspects>
<aspects>
<aspect name="com.stackoverfow.FrameHandling.AspectB"/>
</aspects>
</aspectj>
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.stackoverflow</groupId>
<artifactId>UiTestAutomation</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>pom</packaging>
<name>UiTestAutomation</name>
<properties>
<!-- Maven Plugins -->
<maven-compiler-version>3.6.0</maven-compiler-version>
<maven-surefire-version>2.22.2</maven-surefire-version>
<selenium-version>3.14.0</selenium-version>
<testng-version>7.4.0</testng-version>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>${maven-compiler-version}</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<useIncrementalCompilation>${useIncrementalCompilation} </useIncrementalCompilation>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>${maven-surefire-version}</version>
<configuration>
<argLine>-javaagent:"${settings.localRepository}/org/aspectj/aspectjweaver/1.9.8/aspectjweaver-1.9.8.jar"</argLine>
</configuration>
<executions>
<execution>
<phase>process-sources</phase>
</execution>
</executions>
<dependencies>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.8</version>
</dependency>
</dependencies>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-report-plugin</artifactId>
<version>2.22.2</version>
</plugin>
</plugins>
</build>
<dependencyManagement>
</dependencies>
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-java</artifactId>
<version>${selenium-version}</version>
</dependency>
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-firefox-driver</artifactId>
<version>${selenium-version}</version>
</dependency>
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-htmlunit-driver</artifactId>
<version>${htmlunit-version}</version>
</dependency>
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-support</artifactId>
<version>${selenium-version}</version>
</dependency>
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
<version>${testng-version}</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.aspectj/aspectjrt -->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.8</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>1.9.5</version>
<scope>runtime</scope>
</dependency>
</dependencies>
</dependencyManagement>
</project>
Here AspectA
runs fine on method testNavigation()
AspectB
runs fine on inner method call of NavigationBar.goToHelpPage()
that is present under testNavigation()
method.
When private method takeCareOfNavigationToHomePage()
that is annotated @ChangeToIFrameA
is called AspectA
runs on that method and during the inner method call NavigationBar.goToHomePage()
again AspectA
is called instead of AspectB
. AspectA
call happens twice looks like an overriding is happen.
I see its happening because the private method takeCareOfNavigationToHomePage
is called under login method that is already annotated with TestNG annotation @BeforeClass
. Any idea how to overcome this? Please suggest a solution.