Skip to main content

Terminal Actions

Getting a Terminal Instance

Use SHAFT.CLI.terminal() to get a TerminalActions instance:

TerminalSetup.java
import com.shaft.driver.SHAFT;
import com.shaft.cli.TerminalActions;

TerminalActions terminal = SHAFT.CLI.terminal();

You can also instantiate directly for legacy projects: new TerminalActions().

Execute a Single Command

performTerminalCommand()

Executes a terminal command and returns the standard output as a string.

SingleCommand.java
TerminalActions terminal = SHAFT.CLI.terminal();

String output = terminal.performTerminalCommand("echo Hello SHAFT");
SHAFT.Validations.assertThat().object(output).contains("Hello SHAFT");

Linux / macOS:

LinuxCommands.java
String files = terminal.performTerminalCommand("ls -la /tmp");
String diskUse = terminal.performTerminalCommand("df -h /");
String uptime = terminal.performTerminalCommand("uptime");

Windows:

WindowsCommands.java
String dir = terminal.performTerminalCommand("dir C:\\");
String processes = terminal.performTerminalCommand("tasklist");

Execute Multiple Commands

performTerminalCommands()

Executes a list of commands in sequence and returns the combined output.

MultipleCommands.java
import java.util.Arrays;
import java.util.List;

TerminalActions terminal = SHAFT.CLI.terminal();

List<String> commands = Arrays.asList(
"mkdir -p /tmp/shaft_test",
"echo 'test data' > /tmp/shaft_test/data.txt",
"cat /tmp/shaft_test/data.txt"
);
String output = terminal.performTerminalCommands(commands);
SHAFT.Validations.assertThat().object(output).contains("test data");

Common Use Cases

Test Environment Setup and Teardown

EnvironmentLifecycle.java
import com.shaft.driver.SHAFT;
import com.shaft.cli.TerminalActions;
import org.testng.annotations.*;

public class DatabaseSeedTest {
private TerminalActions terminal;

@BeforeClass
public void setUp() {
terminal = SHAFT.CLI.terminal();
// Seed the database before the test class
terminal.performTerminalCommand("psql -U testuser -d testdb -f src/test/resources/seed.sql");
}

@Test
public void verifyRecordsWereSeeded() {
String result = terminal.performTerminalCommand("psql -U testuser -d testdb -c \"SELECT COUNT(*) FROM users;\"");
SHAFT.Validations.assertThat().object(result).contains("10");
}

@AfterClass
public void tearDown() {
// Clean up test data
terminal.performTerminalCommand("psql -U testuser -d testdb -c \"DELETE FROM users WHERE email LIKE '%test%';\"");
}
}

Build and Deployment Validation

DeploymentTest.java
import com.shaft.driver.SHAFT;
import com.shaft.cli.TerminalActions;
import org.testng.annotations.Test;

public class DeploymentTest {

@Test
public void applicationDeployedSuccessfully() {
TerminalActions terminal = SHAFT.CLI.terminal();

// Trigger deployment
String deployOutput = terminal.performTerminalCommand("./scripts/deploy.sh staging");
SHAFT.Validations.assertThat()
.object(deployOutput)
.contains("Deployment successful")
.withCustomReportMessage("Deploy script should report success");

// Verify the service is running
String healthCheck = terminal.performTerminalCommand("curl -s -o /dev/null -w '%{http_code}' http://localhost:8080/health");
SHAFT.Validations.assertThat()
.object(healthCheck)
.isEqualTo("200")
.withCustomReportMessage("Application health endpoint should return HTTP 200");
}
}

File System Validation

FileSystemValidation.java
import com.shaft.driver.SHAFT;
import com.shaft.cli.TerminalActions;
import org.testng.annotations.Test;

public class FileSystemTest {

@Test
public void exportGeneratesCorrectFile() {
TerminalActions terminal = SHAFT.CLI.terminal();

// Trigger the export via your application's API or UI …
// Then validate the generated file
String exists = terminal.performTerminalCommand("test -f /tmp/export.csv && echo 'found' || echo 'missing'");
SHAFT.Validations.assertThat().object(exists).contains("found");

String lineCount = terminal.performTerminalCommand("wc -l < /tmp/export.csv");
SHAFT.Validations.assertThat()
.object(lineCount.trim()).isNotNull();
}
}

Cross-Platform Compatibility

OSShellExample command
Linux / macOSbashls -la, chmod 755 script.sh, ./deploy.sh
WindowsPowerShelldir, tasklist, Get-Process

When writing cross-platform tests, guard with a platform check:

CrossPlatformCommand.java
String os = System.getProperty("os.name").toLowerCase();
String listCmd = os.contains("win") ? "dir" : "ls -la";
String output = terminal.performTerminalCommand(listCmd);

Timeouts and Reporting

Local commands use shellSessionTimeout; timed-out processes are destroyed and reported as failures. Returned output stays unchanged for assertions, while command/report logs redact common secrets such as tokens, passwords, bearer headers, and URI credentials.

Use the environment-variable overload when a command needs secret input:

CommandEnvironment.java
import java.util.Map;

String output = SHAFT.CLI.terminal().performTerminalCommand(
"echo $env:DEPLOY_TOKEN",
Map.of("DEPLOY_TOKEN", System.getenv("DEPLOY_TOKEN"))
);

Best Practices

  • Always capture and validate output — don't fire-and-forget; check the command succeeded.
  • Use absolute paths — relative paths depend on the working directory and are fragile.
  • Avoid secrets in commands — use environment variables rather than inline passwords.
  • Clean up after yourself — delete temporary files and directories in @AfterMethod / @AfterClass.
  • Check for error keywords — scan output for error, failed, or non-zero exit signals.