Test Automation Framework from Scratch
Building a comprehensive Test Automation Framework (TAF) for a Salesforce-integrated CRM product that had zero automation coverage, transforming a 2-week regression cycle into a 2-day process.
The Challenge
Revenue Grid's flagship product had grown complex with deep Salesforce integrations, multiple email platform connections, and intricate CRM workflows. With zero automation coverage, the QA team was spending 2 weeks on manual regression testing before each release, severely limiting the release cadence and product velocity.
- •Zero test automation - 100% manual testing for all features
- •2-week regression cycles blocking bi-weekly releases
- •Complex Salesforce Lightning component interactions
- •LevelDB log validation requiring manual parsing
- •Cross-platform email sync testing (Outlook, Gmail, Exchange)
The Solution
- Designed and built TAF from scratch using Selenium WebDriver with C#/.NET
- Implemented robust Page Object Model with component-based architecture
- Created custom LevelDB log parser for automated sync validation
- Built Salesforce test harness handling Lightning Web Components
- Established CI/CD pipeline with TeamCity for continuous testing
The framework was built with a focus on stability and maintainability. We implemented smart waits, automatic retry mechanisms for flaky Salesforce elements, and a custom logging system that captured screenshots and DOM snapshots on failures. The LevelDB integration allowed us to validate email sync operations at the database level, not just UI.
Salesforce Component Handler
// Custom Salesforce Lightning component wrapper
public class SalesforceComponentBase : PageObject
{
protected readonly IWebDriver Driver;
protected readonly WebDriverWait Wait;
public SalesforceComponentBase(IWebDriver driver)
{
Driver = driver;
Wait = new WebDriverWait(driver, TimeSpan.FromSeconds(30));
}
protected IWebElement WaitForLightningElement(string selector)
{
return Wait.Until(d => {
var shadow = d.FindElement(By.CssSelector(selector));
// Handle Shadow DOM in Lightning components
var shadowRoot = (IWebElement)((IJavaScriptExecutor)d)
.ExecuteScript("return arguments[0].shadowRoot", shadow);
return shadowRoot?.FindElement(By.CssSelector("slot"));
});
}
protected void ValidateSyncInLevelDB(string recordId)
{
var logParser = new LevelDBLogParser(Config.LogPath);
var syncRecord = logParser.FindSyncEvent(recordId);
Assert.That(syncRecord.Status, Is.EqualTo("SUCCESS"));
}
}Key Results
Quantifiable outcomes achieved through this implementation