AgentStack
SKILL verified MIT Self-run

Sf E2e Testing

skill-jiten-singh-shahi-salesforce-claude-code-sf-e2e-testing · by jiten-singh-shahi

>-

No reviews yet
0 installs
16 views
0.0% view→install

Install

$ agentstack add skill-jiten-singh-shahi-salesforce-claude-code-sf-e2e-testing

✓ scanned · ✓ verified — works with Claude Code, Cursor, and more.

Security review

✓ Passed

No issues found. Passed automated security review. · v0.1.0 How review works →

  • Prompt-injection patterns
  • Secret / credential exfiltration
  • Dangerous shell & filesystem operations
  • Untrusted network calls
  • Known-malicious package signatures

What it can access

  • Network access No
  • Filesystem access No
  • Shell / process execution No
  • Environment & secrets No
  • Dynamic code execution No

From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.

Are you the author of Sf E2e Testing? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claim

About

Salesforce E2E Testing

Comprehensive testing patterns for Salesforce applications including Apex integration tests, LWC component tests, and deployment verification.

Reference: @../reference/TESTINGSTANDARDS.md

When to Use

  • When writing integration tests that exercise complete business workflows end-to-end
  • When verifying full automation chains including triggers, flows, and queueable jobs
  • When setting up pre-deployment verification test suites for a sandbox or production org
  • When testing bulk scenarios with 200+ records across the full trigger and automation stack
  • When building LWC integration tests with Jest that mock Apex wire adapters and calls

Apex Integration Tests

@IsTest
private class OpportunityWorkflowTest {

    @TestSetup
    static void setup() {
        Account acc = new Account(Name = 'E2E Test Account');
        insert acc;

        Opportunity opp = new Opportunity(
            AccountId = acc.Id,
            Name = 'E2E Test Opp',
            StageName = 'Prospecting',
            CloseDate = Date.today().addDays(30),
            Amount = 50000
        );
        insert opp;
    }

    @IsTest
    static void shouldProgressThroughFullSalesCycle() {
        Opportunity opp = [SELECT Id, StageName FROM Opportunity LIMIT 1];

        Test.startTest();

        opp.StageName = 'Qualification';
        update opp;

        opp.StageName = 'Proposal/Price Quote';
        update opp;

        opp.StageName = 'Closed Won';
        update opp;

        Test.stopTest();

        Opportunity result = [SELECT StageName, IsClosed, IsWon FROM Opportunity WHERE Id = :opp.Id];
        Assert.areEqual('Closed Won', result.StageName);
        Assert.isTrue(result.IsClosed, 'Should be closed');
        Assert.isTrue(result.IsWon, 'Should be won');

        // Verify downstream automation fired
        List followUpTasks = [SELECT Id FROM Task WHERE WhatId = :opp.Id];
        Assert.isTrue(!followUpTasks.isEmpty(), 'Should have created follow-up tasks');
    }

    @IsTest
    static void shouldHandleBulkStageChanges() {
        List opps = new List();
        Account acc = [SELECT Id FROM Account LIMIT 1];
        for (Integer i = 0; i = 200, 'All opportunities should be closed');
    }
}

LWC Integration Tests

import { createElement } from 'lwc';
import OpportunityPipeline from 'c/opportunityPipeline';
import getOpportunities from '@salesforce/apex/OpportunityController.getOpportunities';

jest.mock('@salesforce/apex/OpportunityController.getOpportunities', () => ({
    default: jest.fn()
}), { virtual: true });

const MOCK_OPPS = [
    { Id: '006xx0001', Name: 'Opp 1', StageName: 'Prospecting', Amount: 10000 },
    { Id: '006xx0002', Name: 'Opp 2', StageName: 'Closed Won', Amount: 50000 },
];

describe('c-opportunity-pipeline (integration)', () => {
    afterEach(() => { while (document.body.firstChild) document.body.removeChild(document.body.firstChild); });

    it('renders pipeline with correct stage grouping', async () => {
        getOpportunities.mockResolvedValue(MOCK_OPPS);
        const element = createElement('c-opportunity-pipeline', { is: OpportunityPipeline });
        document.body.appendChild(element);

        await Promise.resolve();
        await Promise.resolve();

        const stages = element.shadowRoot.querySelectorAll('.stage-column');
        expect(stages.length).toBeGreaterThan(0);
    });
});

Deployment Verification

# Full E2E deployment verification
sf project deploy validate --test-level RunLocalTests --target-org staging
sf project deploy start --test-level RunLocalTests --target-org staging
sf apex run test --test-level RunLocalTests --result-format human --target-org staging

Flow Integration Testing

@IsTest
private class CaseEscalationFlowTest {

    @IsTest
    static void shouldEscalateHighPriorityCases() {
        Account acc = new Account(Name = 'Flow E2E Account');
        insert acc;

        Case c = new Case(
            AccountId = acc.Id,
            Subject = 'Urgent Issue',
            Priority = 'High',
            Status = 'New'
        );
        insert c;

        Test.startTest();
        c.Status = 'Escalated';
        update c;
        Test.stopTest();

        List tasks = [SELECT Subject, Priority FROM Task WHERE WhatId = :c.Id AND Subject LIKE '%Escalation%'];
        Assert.isTrue(!tasks.isEmpty(), 'Flow should have created escalation task');
        Assert.areEqual('High', tasks[0].Priority, 'Task priority should match case priority');
    }
}

Platform Event Testing

@IsTest
private class OrderEventTest {

    @IsTest
    static void shouldPublishEventOnOrderCompletion() {
        Order_Complete__e event = new Order_Complete__e(
            Order_Id__c = 'ORD-001',
            Total_Amount__c = 5000.00
        );

        Test.startTest();
        Database.SaveResult sr = EventBus.publish(event);
        Test.stopTest();

        Assert.isTrue(sr.isSuccess(), 'Event should publish successfully');
    }

    @IsTest
    static void shouldProcessEventInSubscriber() {
        Order_Complete__e event = new Order_Complete__e(
            Order_Id__c = 'ORD-002',
            Total_Amount__c = 10000.00
        );

        Test.startTest();
        EventBus.publish(event);
        Test.getEventBus().deliver(); // Force trigger subscriber to execute
        Test.stopTest();

        List fulfillments = [
            SELECT Order_Id__c FROM Fulfillment__c WHERE Order_Id__c = 'ORD-002'
        ];
        Assert.areEqual(1, fulfillments.size(), 'Subscriber should have created fulfillment');
    }
}

Async Job Verification

@IsTest
private class AsyncWorkflowTest {

    @IsTest
    static void shouldProcessQueueableChain() {
        Account acc = new Account(Name = 'Async E2E');
        insert acc;

        Test.startTest();
        System.enqueueJob(new AccountEnrichmentJob(acc.Id));
        Test.stopTest();

        Account result = [SELECT Description, Industry FROM Account WHERE Id = :acc.Id];
        Assert.isNotNull(result.Description, 'Enrichment job should populate description');
    }
}

Multi-User Testing

@IsTest
private class PermissionE2ETest {

    @IsTest
    static void shouldRestrictAccessForStandardUser() {
        // Note: Profile names are locale-dependent. For non-English orgs,
        // query by Profile.UserType or use a custom permission set.
        Profile stdProfile = [SELECT Id FROM Profile WHERE Name = 'Standard User'];
        User testUser = new User(
            Alias = 'stdu', Email = 'stduser@test.com',
            EmailEncodingKey = 'UTF-8', LastName = 'StdUser',
            LanguageLocaleKey = 'en_US', LocaleSidKey = 'en_US',
            ProfileId = stdProfile.Id, TimeZoneSidKey = 'America/Los_Angeles',
            UserName = 'stduser' + DateTime.now().getTime() + '@test.com'
        );
        insert testUser;

        System.runAs(testUser) {
            Test.startTest();
            try {
                ConfidentialRecord__c rec = new ConfidentialRecord__c(Name = 'Secret');
                insert rec;
                Assert.fail('Should have thrown insufficient access exception');
            } catch (DmlException e) {
                Assert.isTrue(e.getMessage().contains('INSUFFICIENT_ACCESS') ||
                             e.getMessage().contains('access'),
                             'Should get access denied: ' + e.getMessage());
            }
            Test.stopTest();
        }
    }
}

Performance Assertions

@IsTest
private class PerformanceE2ETest {

    @IsTest
    static void shouldStayWithinGovernorLimits() {
        List accounts = new List();
        for (Integer i = 0; i (accounts).keySet());

        Integer queriesUsed = Limits.getQueries() - queriesBefore;
        Test.stopTest();

        Assert.isTrue(queriesUsed <= 5,
            'Should use <= 5 SOQL queries for 200 records, used: ' + queriesUsed);
    }
}

Anti-Patterns

| Anti-Pattern | Problem | Fix | |-------------|---------|-----| | Testing with 1 record only | Misses bulkification bugs | Test with 200+ records | | No Test.startTest/stopTest | Governor limits from setup count against test | Wrap test logic in startTest/stopTest | | Using SeeAllData=true | Tests depend on org data, fail unpredictably | Use @TestSetup with test-specific data | | Hardcoded IDs | Break across orgs and sandboxes | Query for IDs or use TestDataFactory | | No downstream verification | Trigger fires but automation not verified | Assert on records created by automation | | Ignoring async results | Queueable/Batch results not checked | Test.stopTest forces execution, then assert |

Best Practices

  • Use @TestSetup for shared test data across methods
  • Test complete workflows, not just individual methods
  • Include bulk tests (200+ records) for all trigger-based automation
  • Test both happy path and error scenarios
  • Verify downstream automation by checking created records
  • Use Test.startTest()/Test.stopTest() to isolate governor limit counting
  • Use Test.getEventBus().deliver() to force Platform Event subscriber execution
  • Use System.runAs() to test permission and sharing model enforcement
  • Assert governor limit consumption for performance-sensitive code
  • For HTTP callout tests, use Test.setMock(HttpCalloutMock.class, mock) -- see the sf-integration skill for mock patterns

Related

  • Constraints: sf-testing-constraints -- test isolation rules, assertion requirements, coverage gates

Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

Install and usage instructions live in the source repository linked above.

Reviews

No reviews yet — be the first.

Versions

  • v0.1.0 Imported from the upstream source.