Salesforce QA Automation

Run Salesforce test scenarios using the Crank BDD framework.

Salesforce Logo

Test your Salesforce Workflow and Process Builder automation as rigorously as you test your Apex code.

Salesforce Alert QA

Make sure Account owners receive alerts for high priority cases.

- step: Given I create a Salesforce Case object with...
  data:
    SuppliedName: High Priority Case (Test)
    Priority: High
    AccountId: '{{Fixtures.Accounts.PlatinumSLA.Id}}'
- step: Then there should be 1 email in mailgun for {{Fixtures.Users.PlatinumSLA.Email}}
  failAfter: 60
- step: And the subject of the 1st mailgun email for {{Fixtures.Users.PlatinumSLA.EmailAddress}} should contain High Priority Case Alert
Salesforce Lead Sync QA

Make sure lead updates are synced back to marketing automation.

- step: Given I create a Salesforce Lead with...
  data:
    Email: '{{Test.Email}}'
    FirstName: '{{Test.GivenName}}'
    LastName: '{{Test.FamilyName}}'
    Company: '{{Test.Company}}'
- waitFor: 60
  step: Then the Status__c field on Marketo Lead {{Test.Email}} should be Open - Not Contacted
- step: And when I update the Salesforce Lead object identified by Id {{salesforce.lead.Id}} with...
  data:
    Status: Working - Contacted
- waitFor: 60
  step: Then the Status__c field on Marketo Lead {{Test.Email}} should be Working - Contacted

What is Crank?

Crank is a BDD test automation framework for SaaS-based business technology.

Developer Getting StartedHosted QA Automation for Business Users

Installing and Authenticating this Cog

Once you've successfully installed Crank you can install this Cog by running the following:

$ crank cog:install automatoninc/salesforce

You will be asked for the following authentication details on installation. To avoid prompts in a CI/CD context, you can provide the same details as environment variables.

Expected Authentication Details
FieldInstall-Time Environment VariableDescription
instanceUrl *CRANK_AUTOMATONINC_SALESFORCE__INSTANCEURLLogin/instance URL (e.g. https://na1.salesforce.com)
clientId *CRANK_AUTOMATONINC_SALESFORCE__CLIENTIDOAuth2 Client ID
clientSecret *CRANK_AUTOMATONINC_SALESFORCE__CLIENTSECRETOAuth2 Client Secret
username *CRANK_AUTOMATONINC_SALESFORCE__USERNAMEUsername
password *CRANK_AUTOMATONINC_SALESFORCE__PASSWORDPassword

You can always re-authenticate by running the following command.

$ crank cog:auth automatoninc/salesforce
Further Auth Details Here

Salesforce Test Steps

Create a Salesforce Account Action

Use this step in a Scenario file like this:

- step: When I create a salesforce account
  data:
    account:
      field: value
Expected Step Input
IDTypeDescription
account *Map/ObjectA map of field names to field values
Exposed Dynamic Tokens
TokenTypeDescription
{{salesforce.account.Id}}StringAccount's SalesForce ID

Create a Salesforce Contact Action

Use this step in a Scenario file like this:

- step: When I create a salesforce contact
  data:
    contact:
      field: value
Expected Step Input
IDTypeDescription
contact *Map/ObjectA map of field names to field values
Exposed Dynamic Tokens
TokenTypeDescription
{{salesforce.contact.Id}}StringContact's SalesForce ID

Create a Salesforce Lead Action

Use this step in a Scenario file like this:

- step: When I create a salesforce lead
  data:
    lead:
      field: value
Expected Step Input
IDTypeDescription
lead *Map/ObjectA map of field names to field values
Exposed Dynamic Tokens
TokenTypeDescription
{{salesforce.lead.Id}}StringLead's SalesForce ID

Create a Salesforce Object Action

Use this step in a Scenario file like this:

- step: When I create a salesforce {{objName}} object
  data:
    salesforceObject:
      field: value
Expected Step Input
IDTypeDescription
objName *StringSalesforce object name
salesforceObject *Map/Objectwhere keys represent object field names as represented in the SFDC API
Exposed Dynamic Tokens
TokenTypeDescription
{{salesforce.salesforceObject.Id}}StringObject's SalesForce ID

Create a Salesforce Opportunity Action

Use this step in a Scenario file like this:

- step: When I create a salesforce opportunity
  data:
    opportunity:
      field: value
Expected Step Input
IDTypeDescription
opportunity *Map/ObjectA map of field names to field values
Exposed Dynamic Tokens
TokenTypeDescription
{{salesforce.opportunity.Id}}StringOpportunity's SalesForce ID

Delete a Salesforce Account Action

Use this step in a Scenario file like this:

- step: Finally, delete the salesforce account with {{field}} {{identifier}}
Expected Step Input
IDTypeDescription
field *Stringthe name of the field used to identify the account
identifier *Any Scalarthe value of the field
Exposed Dynamic Tokens
TokenTypeDescription
{{salesforce.account.Id}}StringAccount's SalesForce ID

Delete a Salesforce Contact Action

Use this step in a Scenario file like this:

- step: Finally, delete the {{email}} salesforce contact
Expected Step Input
IDTypeDescription
email *Email AddressContact's Email Address
Exposed Dynamic Tokens
TokenTypeDescription
{{salesforce.contact.Id}}StringContact's SalesForce ID

Delete a Salesforce Lead Action

Use this step in a Scenario file like this:

- step: Finally, delete the {{email}} salesforce lead
Expected Step Input
IDTypeDescription
email *Email AddressLead's email address
Exposed Dynamic Tokens
TokenTypeDescription
{{salesforce.lead.Id}}StringLead's SalesForce ID

Delete a Salesforce Object Action

Use this step in a Scenario file like this:

- step: Finally, delete the salesforce {{objName}} object with id {{id}}
Expected Step Input
IDTypeDescription
objName *StringSalesforce Object name
id *StringObject ID
Exposed Dynamic Tokens
TokenTypeDescription
{{salesforce.salesforceObject.Id}}StringObject's SalesForce ID

Delete a Salesforce Opportunity Action

Use this step in a Scenario file like this:

- step: Finally, delete the salesforce opportunity with {{field}} {{identifier}}
Expected Step Input
IDTypeDescription
field *Stringthe name of the field used to identify the opportunity
identifier *Any Scalarthe value of the field
Exposed Dynamic Tokens
TokenTypeDescription
{{salesforce.opportunity.Id}}StringOpportunity's SalesForce ID

Update a Salesforce Object Action

Use this step in a Scenario file like this:

- step: When I update the salesforce {{objName}} object identified by id {{identifier}}
  data:
    salesforceObject:
      field: value
Expected Step Input
IDTypeDescription
objName *StringSalesforce object name
identifier *StringSalesforce object ID
salesforceObject *Map/Objectwhere keys represent object field names as represented in the SFDC API
Exposed Dynamic Tokens
TokenTypeDescription
{{salesforce.salesforceObject.Id}}StringObject's SalesForce ID

Check a field on a Salesforce Account Assertion

Use this step in a Scenario file like this:

- step: Then the {{field}} field on salesforce account with {{idField}} {{identifier}} should {{operator}} {{expectedValue}}
Expected Step Input
IDTypeDescription
idField *StringThe field used to search/identify the account
identifier *Any ScalarThe value of the id field to use when searching
field *StringThe name of the field to check
operator StringCheck Logic (be, not be, contain, not contain, be greater than, be less than, be set, not be set, be one of, or not be one of)
expectedValue Any ScalarThe expected value of the field
Exposed Dynamic Tokens
TokenTypeDescription
{{salesforce.account.Id}}StringAccount's SalesForce ID
{{salesforce.account.CreatedDate}}ISO 8601 DatetimeAccount's Created Date
{{salesforce.account.LastModifiedDate}}ISO 8601 DatetimeAccount's Last Modified Date
{{salesforce.account.*}}*This step may expose additional dynamic tokens representing values on the account, depending on how you've configured the underlying system.

Check a field on a Salesforce Campaign Member Assertion

Use this step in a Scenario file like this:

- step: Then the salesforce lead {{email}} should have campaign member {{field}} {{operator}} {{expectedValue}} on campaign {{campaignId}}
Expected Step Input
IDTypeDescription
email *Email AddressLead's email address
campaignId *StringCampaign ID
field *StringField name to check
operator StringCheck Logic (set to, not set to, containing, not containing, greater than, less than, set, not set, set to one of, or not set to one of)
expectedValue Any ScalarExpected field value
Exposed Dynamic Tokens
TokenTypeDescription
{{salesforce.campaignMember.Id}}StringCampaign Member's SalesForce ID
{{salesforce.campaignMember.CreatedDate}}ISO 8601 DatetimeCampaign Member's Created Date
{{salesforce.campaignMember.LastModifiedDate}}ISO 8601 DatetimeCampaign Member's Last Modified Date
{{salesforce.campaignMember.CampaignId}}StringCampaign Member's Campaign Id
{{salesforce.campaignMember.LeadId}}StringCampaign Member's Lead Id
{{salesforce.campaignMember.ContactId}}StringCampaign Member's Contact Id
{{salesforce.campaignMember.LeadOrContactId}}StringCampaign Member's Lead or Contact Id
{{salesforce.campaignMember.*}}*This step may expose additional dynamic tokens representing values on the campaignMember, depending on how you've configured the underlying system.

Check a field on a Salesforce Contact Assertion

Use this step in a Scenario file like this:

- step: Then the {{field}} field on salesforce contact {{email}} should {{operator}} {{expectedValue}}
Expected Step Input
IDTypeDescription
email *Email AddressContact's email address
field *StringField name to check
operator StringCheck Logic (be, not be, contain, not contain, be greater than, be less than, be set, not be set, be one of, or not be one of)
expectedValue Any ScalarExpected field value
Exposed Dynamic Tokens
TokenTypeDescription
{{salesforce.contact.Id}}StringContact's SalesForce ID
{{salesforce.contact.CreatedDate}}ISO 8601 DatetimeContact's Created Date
{{salesforce.contact.LastModifiedDate}}ISO 8601 DatetimeContact's Last Modified Date
{{salesforce.contact.*}}*This step may expose additional dynamic tokens representing values on the contact, depending on how you've configured the underlying system.

Check a field on a Salesforce Lead Assertion

Use this step in a Scenario file like this:

- step: Then the {{field}} field on salesforce lead {{email}} should {{operator}} {{expectedValue}}
Expected Step Input
IDTypeDescription
email *Email AddressLead's email address
field *StringField name to check
operator StringCheck Logic (be, not be, contain, not contain, be greater than, be less than, be set, not be set, be one of, or not be one of)
expectedValue Any ScalarExpected field value
Exposed Dynamic Tokens
TokenTypeDescription
{{salesforce.lead.Id}}NumberLead's SalesForce ID
{{salesforce.lead.CreatedDate}}ISO 8601 DatetimeLead's Created Date
{{salesforce.lead.LastModifiedDate}}ISO 8601 DatetimeLead's Last Modified Date
{{salesforce.lead.*}}*This step may expose additional dynamic tokens representing values on the lead, depending on how you've configured the underlying system.

Check a field on a Salesforce Object Assertion

Use this step in a Scenario file like this:

- step: Then the {{field}} field on salesforce {{objName}} object with id {{id}} should {{operator}} {{expectedValue}}
Expected Step Input
IDTypeDescription
objName *StringSalesforce object name
id *StringObject ID
field *StringField name to check
operator *StringCheck Logic (be, not be, contain, not contain, be greater than, be less than, be set, not be set, be one of, or not be one of)
expectedValue Any ScalarExpected field value
Exposed Dynamic Tokens
TokenTypeDescription
{{salesforce.salesforceObject.Id}}NumberObject's SalesForce ID
{{salesforce.salesforceObject.CreatedDate}}ISO 8601 DatetimeObject's Created Date
{{salesforce.salesforceObject.LastModifiedDate}}ISO 8601 DatetimeObject's Last Modified Date
{{salesforce.salesforceObject.*}}*This step may expose additional dynamic tokens representing values on the salesforceObject, depending on how you've configured the underlying system.

Check a field on a Salesforce Opportunity Assertion

Use this step in a Scenario file like this:

- step: Then the {{field}} field on salesforce opportunity with {{idField}} {{identifier}} should {{operator}} {{expectedValue}}
Expected Step Input
IDTypeDescription
idField *StringThe field used to search/identify the opportunity
identifier *Any ScalarThe value of the id field to use when searching
field *StringThe name of the field to check
operator StringCheck Logic (be, not be, contain, not contain, be greater than, be less than, be set, not be set, be one of, or not be one of)
expectedValue Any ScalarThe expected value of the field
Exposed Dynamic Tokens
TokenTypeDescription
{{salesforce.opportunity.Id}}StringOpportunity's SalesForce ID
{{salesforce.opportunity.CreatedDate}}ISO 8601 DatetimeOpportunity's Created Date
{{salesforce.opportunity.LastModifiedDate}}ISO 8601 DatetimeOpportunity's Last Modified Date
{{salesforce.opportunity.*}}*This step may expose additional dynamic tokens representing values on the opportunity, depending on how you've configured the underlying system.

Check Salesforce Campaign Membership Assertion

Use this step in a Scenario file like this:

- step: Then the salesforce lead {{email}} should be a member of campaign {{campaignId}}
Expected Step Input
IDTypeDescription
email *Email AddressLead's email address
campaignId *StringCampaign ID
Exposed Dynamic Tokens
TokenTypeDescription
{{salesforce.campaignMember.Id}}StringCampaign Member's SalesForce ID
{{salesforce.campaignMember.CreatedDate}}ISO 8601 DatetimeCampaign Member's Created Date
{{salesforce.campaignMember.LastModifiedDate}}ISO 8601 DatetimeCampaign Member's Last Modified Date
{{salesforce.campaignMember.CampaignId}}StringCampaign Member's Campaign Id
{{salesforce.campaignMember.LeadId}}StringCampaign Member's Lead Id
{{salesforce.campaignMember.ContactId}}StringCampaign Member's Contact Id
{{salesforce.campaignMember.LeadOrContactId}}StringCampaign Member's Lead or Contact Id
{{salesforce.campaignMember.*}}*This step may expose additional dynamic tokens representing values on the campaignMember, depending on how you've configured the underlying system.

Missing a Step You Need?

This Cog is open source! Your contributions are welcome and encouraged.

Contribute on GitHubJoin the Crank Spectrum Community