Skip to main content

Install, Upgrade & Migrate

This guide covers three scenarios:

ScenarioSection
Fresh install into a blank Maven project→ Fresh Install
Upgrade an existing SHAFT project to the latest version→ Upgrading SHAFT
Migrate a native Selenium / Appium / REST Assured project→ Migrating from Native Selenium

System Requirements

RequirementMinimumRecommended
JavaJava 21 LTSJava 21 LTS
Maven3.8+Latest stable
IDEIntelliJ IDEA, EclipseIntelliJ IDEA
OSWindows, macOS, LinuxAny
Why Java 21?

SHAFT uses Java 21 virtual threads to power driver.async().element() — non-blocking parallel element actions. Java 21 is the current LTS release and is required. Set <java.version>21</java.version> in your pom.xml.


Fresh Install

Step 1 — Add the Dependency

Add SHAFT to your pom.xml:

pom.xml
<properties>
<java.version>21</java.version>
<maven.compiler.source>${java.version}</maven.compiler.source>
<maven.compiler.target>${java.version}</maven.compiler.target>
</properties>

<dependencies>
<dependency>
<groupId>io.github.shafthq</groupId>
<artifactId>SHAFT_ENGINE</artifactId>
<version>10.2.20260501</version>
</dependency>
</dependencies>
Always use a pinned version

Replace 10.2.20260501 with the latest release from Maven Central. Using RELEASE is not recommended for reproducible builds.

Step 2 — Add a Properties File

Create src/main/resources/properties/custom.properties (SHAFT auto-creates the directory on first run but you can pre-create it):

src/main/resources/properties/custom.properties
# Browser (chrome | firefox | microsoftedge | safari)
targetBrowserName=chrome

# Run headless in CI
headlessExecution=false

# Screenshots
screenshotParams_whenToTakeAScreenshot=ValidationPointsOnly

Step 3 — Write Your First Test

src/test/java/tests/MyFirstTest.java
import com.shaft.driver.SHAFT;
import org.openqa.selenium.By;
import org.testng.annotations.*;

public class MyFirstTest {
private SHAFT.GUI.WebDriver driver;

@Test
public void searchOnDuckDuckGo() {
driver.browser().navigateToURL("https://duckduckgo.com/")
.and().element().type(By.name("q"), "SHAFT Engine test automation")
.and().element().click(By.cssSelector("button[type='submit']"))
.and().assertThat().browser().title().contains("SHAFT").perform();
}

@BeforeMethod
public void setUp() {
driver = new SHAFT.GUI.WebDriver();
}

@AfterMethod
public void tearDown() {
driver.quit();
}
}

Step 4 — Run

Terminal
mvn test

The Allure report opens automatically in your browser when all tests finish.


Upgrading SHAFT

Find the Latest Version

Check Maven Central or the GitHub Releases page for the latest version.

Current latest: 10.2.20260501

Update pom.xml

pom.xml — update the version tag
<dependency>
<groupId>io.github.shafthq</groupId>
<artifactId>SHAFT_ENGINE</artifactId>
<version>10.2.20260501</version> <!-- update this line -->
</dependency>

Refresh Dependencies

Right-click pom.xmlMavenReload Project, or click the 🔄 Load Maven Changes notification.

Upgrade Checklist

After updating the version, run through this checklist:

  • Run the full test suitemvn test — to catch any compatibility issues.
  • Review the release notes for breaking changes in the new version.
  • Update property files if any new properties were introduced (SHAFT writes updated defaults on first run).
  • Check deprecated API usage — IntelliJ will highlight strikethrough methods. Follow the Javadoc for the replacement.
  • Verify Java version — confirm <java.version>21</java.version> is set in your pom.xml.

Version History (Recent)

VersionReleasedHighlights
10.2.202605012026-05-01Fix waitUntil lambda expressions, fix Equals on incomparable types, CI improvements, httpclient5 security fix
10.2.202604112026-04-11Selenium 4.43, dependency tree cleanup, removed all deprecated methods
10.1.202603312026-03-31Stability improvements, Dependabot updates

For older version history see the GitHub Releases archive.


Migrating from Native Selenium

Already have a Selenium, Appium, or REST Assured project? Add SHAFT incrementally — your existing By locators and test logic stay unchanged.

Step 1 — Add the SHAFT Dependency

Same as Fresh Install Step 1 above.

Step 2 — Replace Driver Initialization

Before — native Selenium
WebDriver driver = new ChromeDriver();
driver.manage().window().maximize();
After — SHAFT (browser configured via properties)
SHAFT.GUI.WebDriver driver = new SHAFT.GUI.WebDriver();
// browser type, size, and capabilities are in custom.properties — no code change needed

Step 3 — Remove Manual Waits

SHAFT auto-waits for every element action. Remove WebDriverWait and Thread.sleep() calls:

Before
WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(10));
wait.until(ExpectedConditions.elementToBeClickable(By.id("submit")));
driver.findElement(By.id("submit")).click();
After — SHAFT waits automatically
driver.element().click(By.id("submit"));

The default timeout is configurable via:

custom.properties
elementIdentificationTimeout=5 # seconds to wait for element

Step 4 — Switch to SHAFT Assertions

Replace TestNG/JUnit assertions with SHAFT's built-in validation chain for rich report output:

Before
Assert.assertEquals(driver.getTitle(), "Dashboard | My App");
Assert.assertTrue(driver.findElement(By.id("welcome")).isDisplayed());
After — SHAFT assertions with Allure reporting
driver.assertThat().browser().title().isEqualTo("Dashboard | My App").perform();
driver.assertThat(By.id("welcome")).isDisplayed().perform();

Step 5 — Externalize Configuration

Move hard-coded browser, URL, and credential values to custom.properties:

Before — hard-coded
driver.get("https://staging.myapp.com");
After — value from environment or property
// In custom.properties or set via CLI: -DbaseUrl=https://staging.myapp.com
String baseUrl = SHAFT.Properties.flags.baseURL();
driver.browser().navigateToURL(baseUrl);

Migration Pace

You do not need to migrate everything at once. A safe incremental order is:

  1. Replace driver initialization → let SHAFT manage browser lifecycle
  2. Remove explicit waits → rely on SHAFT auto-wait
  3. Replace assertions → use driver.assertThat() / SHAFT.Validations
  4. Externalize configuration → properties files or CLI flags
  5. Adopt fluent chaining → use .and() to chain actions
Keep native access when needed

At any point you can drop back to the underlying Selenium WebDriver:

WebDriver nativeDriver = driver.getDriver();

SHAFT never locks you in.