Giter Site home page Giter Site logo

lightningtestingservice's Introduction

Lightning Testing Service (LTS) CircleCI

Lightning Testing Service Overview

NOTICE: This tool is no longer supported and no additional work is planned for this tool. We recommend if you want to use this tool, that you treat it as an example and create your own fork of it to use in your build process

The Lightning Testing Service, or LTS, is a set of tools and services that let you create test suites for your Aura components using standard JavaScript test frameworks, such as Jasmine and Mocha.

Note: As of Spring '19, the Lightning Component framework has two programming models, Lightning Web Components, and Aura Components, the original model. Use LTS to test Aura components.

Automated tests are the best way to achieve predictable, repeatable assessments of the quality of your custom code. Writing automated tests for your custom components gives you confidence that they work as designed, and allows you to evaluate the impact of changes, such as refactoring, or of new versions of Salesforce or third-party JavaScript libraries.

The LTS supports testing with standard JavaScript test frameworks. We provide easy-to-use wrappers for using Jasmine and Mocha. If you prefer to use an alternative test framework, you can wrap it yourself. (See Next Steps for some details.)

Getting Started with Lightning Testing Service

LTS and Salesforce CLI are two great tastes that taste great together. Installing the LTS is a one line command in the Salesforce CLI. Once installed, you can work with your test suite in a variety of ways from the command line. This approach also facilitates systematic automated testing.

Note: If you just want to “kick the tires,” that's cool, too. You can manually install the LTS unmanaged package. The package provides the test service app and an example test suite. It also includes example components that the test suite runs against. You run the test suite by accessing the URL for the LTS app in your org.

Write your tests using a JavaScript testing framework of your choosing. We provide easy-to-use wrappers for Jasmine and Mocha.

A simple Jasmine test spec looks like the following:

/**
 * This is a 'hello world' Jasmine test spec
 */
describe("A simple passing test", function () {
  it("checks that true is always true", function () {
    expect(true).toBe(true);
  });
});

A similar Mocha test looks, well, similar:

/**
 * This is a 'hello world' Mocha test
 */
var assert = require("assert");
describe("Test the nature of truth", function () {
  describe("A simple passing test", function () {
    it("checks that true is always true", function () {
      assert.equal(true, true);
    });
  });
});

You can write your own wrapper if you prefer a different testing framework. It's not hard, but plan on half a day to a day of work.

The LTS also provides utilities specific to the Lightning Component framework, which let you test behavior specific to Aura components. Details are explained in comments in the example tests.

Your test suite is deployed in the form of an archive (zip) static resource. Once the LTS is installed and configured, you make changes to your test suite, create the archive, and upload it to your org. Once uploaded you can run the test suite via the command line or via URL.

Important: Don't run tests in your production org. The LTS doesn't provide an isolated test context or transaction wrapper. DML operations you perform in your tests won't be rolled back at the end of the test. We recommend that you run your LTS test suites only in scratch orgs, using data provided by the test suite itself.

Installing the Lightning Testing Service

There are two ways you can install the LTS. The simplest is to use the Salesforce CLI. If you're not using the Salesforce CLI, you can manually install the unmanaged package.

Install the Lightning Testing Service with the Salesforce CLI

The Salesforce CLI includes a one line command for automatically installing the LTS unmanaged package. The Salesforce CLI also allows you to use the sfdx command line tool to perform automated testing as part of your development process, including automated process, such as continuous integration.

NOTICE: When installing the CLI Plugin, an external request is made to https://api.github.com/repos/forcedotcom/LightningTestingService/releases/ in order to download supporting files for the plugin. If this URL is blocked by your firewall, the installation of the plugin will fail.

  1. If you haven't already, install the Salesforce CLI by following the instructions for your operating system:

    Install the Salesforce CLI in the Salesforce CLI Setup Guide

  2. Verify that the Salesforce CLI plug-in is installed and updated by running the following command in your shell or terminal application:

    sfdx update

    Additional verification details are available in Verify Your Installation and Install the Plug-In in the Salesforce CLI Setup Guide.

  3. Install the LTS CLI Plugin with the following command:

    sfdx plugins:install plugin-lightning-testing-service
  4. Install the LTS package with the following command:

    sfdx aura-test:install

    This installs the latest version of the LTS package into your default SFDX org. See the help for the install command for additional options.

After you install LTS, you can run your tests from the command line using the sfdx tool. For example:

sfdx force:auth:web:login -s     # connect to your scratch org
sfdx force:source:push           # push local source to the scratch org
sfdx aura-test:run -a jasmineTests.app   # run the test suite

When you run the aura-test:run -a jasmineTests.app command in a connected workspace you should see something like the following:

Console output from a successful test suite execution using sfdx

This tells you that the command line tools are working, and connected to your development org.

Install the Lightning Testing Service Unmanaged Package Manually

If you're not using the Salesforce CLI, you're missing out on a lot, but you can still use LTS. Installing the LTS package is just like installing any other unmanaged package.

  1. Log in to your org. We recommend that you create a new DE org for evaluating the LTS.
  2. Go to the project Releases page, and click the package installation URL for the latest release.
  3. Authenticate again with the credentials for your DE org.
  4. Follow the normal package installation prompts. We recommend installing the package for admins only.

Touring the Lightning Testing Service

However you install it, the LTS package includes the following items:

  • Example test suites
    • Jasmine JavaScript files in archive static resources
    • Mocha JavaScript files in archive static resources
  • Example components to be tested
    • Components, an Apex class, and a custom label
  • LTS infrastructure
    • Jasmine framework and wrapper
    • Mocha framework and wrapper
    • LTS test utilities
    • Test runner component
    • Wrapper test app

Once installed, you can run the example test suite by going to the following URL in your org: https://<myServer>/c/jasmineTests.app (Jasmine) https://<myServer>/c/mochaTests.app (Mocha)

You should see a screen that looks something like the following.

Successful execution of the jasmineTests.app tests

This page tells you that the package is correctly installed and LTS is working in your org.

Next Steps

When you have the LTS package installed and working in your org, you’re ready to begin exploring the test code, and even writing your own tests. Here are some next steps for you to take.

Explore the Example Test Suites

To dive into the test suites and start learning how to write tests for your Aura components, explore the tests and the components being tested side-by-side. You’ll want to open the test suite file in one window, and in another window (perhaps in your IDE) open the simple components being tested.

Both the components and the test suites included in the unmanaged package are also available in a repository on GitHub:

https://github.com/forcedotcom/LightningTestingService

Components for Testing

All of the testable components are named beginning with “eg” (from the abbreviation “e.g.”, meaning for example). The components provided in the package can be accessed as you would any Aura component.

  • In the Developer Console
  • In the Force.com IDE, in the /aura/ directory
  • By converting your org’s metadata into a format that you can work with locally, using Salesforce CLI

You can also explore the components directly from the repo. They’re available in the lightning-component-tests/main/default/aura directory.

There are more than a dozen different components, designed to be used in illustrative tests. Each of the components has a description of its behavior in its .auradoc documentation file.

Test Suites

The example tests are included in the form of static resources. You can also review them directly in the repo, in the lightning-component-tests/test/default/staticresources directory.

There are four test suites included in the LTS package, three for Jasmine and one for Mocha:

  • jasmineHelloWorldTests.resource — A very simple Jasmine example including one passing and one failing test.
  • jasmineExampleTests.resource — The main Jasmine example test suite.
  • jasmineLightningDataServiceTests.resource — Some Jasmine examples specific to testing Lightning Data Service-based components.
  • mochaExampleTests.resource — The Mocha example test suite, which provides examples parallel to the main Jasmine test suite.

The remainder of the static resources are infrastructure used by the LTS. They’re briefly described in Use Another JavaScript Test Framework.

The jasmineExampleTests.resource and mochaExampleTests.resource files are each a single JavaScript file containing a complete test suite. It’s a single file for convenience in delivery and exploration. Your own test suites can include many such files. The test suites are copiously commented. The code and comments serve as the official documentation for how to write tests.

Write Your Own Tests

A separate document, Testing Lightning Components with the Lightning Testing Service, describes the flow, or lifecycle, of using the LTS to automate your testing. Once you’ve explored the example tests, use this document to dive into writing a test suite for your own custom components.

Use Another JavaScript Test Framework

The Lightning Testing Service provides a way to use standard JavaScript test frameworks with your Aura components. We’ve provided the example test suites implemented in Jasmine and Mocha. These are well-regarded test frameworks, and if you haven’t chosen one already, we recommend you start with one of them.

If you’d prefer to use another test framework, either because you’ve already selected one, or because you find something more to your taste, you can use it with the LTS instead.

All of the packaged pieces of the LTS are included in the project repository, in the lightning-component-tests/test/default directory. The pieces you’ll need to modify or replace are the following items, drawn from the Jasmine wrapper.

  • aura/jasmineTests — The front end of the LTS, this simple app includes the test runner component, and a list of test suites to feed it.
  • aura/lts_jasmineRunner — The test runner component for Jasmine. It includes references to the required Jasmine library, which it loads along with the test spec resources, and then fires the test runner.
  • lts_jasmine.resource — The Jasmine library, unmodified.
  • lts_jasmineboot.resource — A JavaScript IIFE that launches Jasmine in the LTS context.
  • lts_testutil.resource — A collection of utilities for use within your test specs, and by the test framework wrappers. They provide Lightning component-specific functions that make it easier to test your custom components from a test context.

The Mocha version of the framework wrapper provides similar files. You might find the similarities and differences instructive in creating your own adapter for other frameworks.

If you’re already experienced with setting up another test framework, adapting the Jasmine examples should take you a day or so, but not longer. We’d be thrilled to hear more about your adventures with other JavaScript test frameworks!

lightningtestingservice's People

Contributors

aheber avatar alderete-sfdc avatar cdengsfdc avatar esalman-sfdc avatar jbleylesf avatar krisgraysfdc avatar louis-bompart avatar muenzpraeger avatar shetzel avatar svc-scm avatar vazexqi avatar wadewegner avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

lightningtestingservice's Issues

Example using config file for WebDriver settings

There doesn't seem to be any way to figure out how to configure the WebDriver settings.

When I run look at the documentation for sfdx force:lightning:test:run (https://developer.salesforce.com/docs/atlas.en-us.sfdx_cli_reference.meta/sfdx_cli_reference/cli_reference_force_lightning.htm#cli_reference_test_run) - there is a --configfile option that says the following:

Path to a test configuration file to configure WebDriver and other settings. For details, see the LTS documentation.

Where is this documentation? I am attempting to run this on a CI tool (like Jenkins) for automated testing and seeing the following error message:

ERROR: not found: java.

I assume it is because I need to install a WebDriver, but there doesn't seem to be any documentation around this. Could you please point me in the right direction?

mocha hooks failures not reported

According to https://github.com/mochajs/mocha/blob/master/lib/runner.js#L42-L54 there are a few events that can happen.

Currently, the mocha suite test reporter (https://github.com/forcedotcom/LightningTestingService/blob/master/lightning-component-tests/test/default/staticresources/lts_testutil.resource#L193-L212) uses the following event:

mochaRunner.on('test end', function (test) {

unfortunately, this does not include hook failures in the report.

My proposal would be to switch out the logic to something more like:

$T._convertMochaEventToTestResult = function(test) {
  console.log(test.state, test.title, '-' + test.duration + 'ms');
  return {
    FullName: test.parent.title + ' : ' + test.title,
    Outcome: test.state,
    RunTime: test.duration,
    Message: test.err ? test.err.message : null
  };
}

$T._sfdxReportForMocha = function (mochaRunner) {
        var run_results_full = { "tests": [] };
        mochaRunner.on('fail', function(test) {
            run_results_full.tests.push($T._convertMochaEventToTestResult(test));
        }).on('pass', function(test) {
            run_results_full.tests.push($T._convertMochaEventToTestResult(test));
        }).on('pending', function(test) {
            test.err = {
              message: ' # SKIP disabled by xit or similar'
            };
            run_results_full.tests.push($T._convertMochaEventToTestResult(test));
        }).on('end', function (suite) {
            setHiddenDivContent("run_results_full", JSON.stringify(run_results_full));
        });
    }

this captures both test failures and beforeEach failures

I can try to get a PR up sometime if others think this is useful

Use full name of hierarchy for test reporting

On test reporting with mocha, the line at https://github.com/forcedotcom/LightningTestingService/blob/master/lightning-component-tests/test/default/staticresources/lts_testutil.resource#L196

indicates that we only get the immediate parent's title for the description.

Is there either way to

  1. specify the filename or
  2. specify the entire parent hierarchy for the fullname

if i have a test that looks like

describe('MyComponent', () => {
  describe('when I do X', () => {
     it('should do Y', () => {
     });
     describe('then I do A', () => {
        it('should do B', () => {
        });
     });
  });
});

I won't know what file the output is coming from when the test result full name is:

then I do A : should do B

the goal here is to set up a file for each component to test its behaviors independently of the other components rather than having one giant file (and hopefully nested behaviors for reusability of events)

support for sinon

Does jasmine in Lightning Testing Service support sinon?

It would be a nice feature to have. For example, I could mock $A.enqueueAction in order to simulate my Apex controller AuraEnabled method, without exposing the action callback as an aura:method, and test response state as SUCCESS, INCOMPLETE and ERROR.

lightning:select breaks test with Error ID: 2004951991-66946

I just spent quite some time tracking down why a simple test was breaking, as the error message didn't give any indication of what the problem is.

I'm using a fresh install using the CLI install command. All the tests work apart from the data service tests which have already been reported.

How to replicate:

Add a lightning:select to the markup without a label (not a blank label, the entire label attribute missing).

Notes:

While label is a required attribute, a lightning:select renders, and does not error, when used on a component normally without the attribute.

Unable to get the child component reference from parent component

I am trying to get the reference of a child component(dropdown) from the parent component. I have defined the aura id of the child component as I have used the same component multiple time in the parent component. Now to test the child component when I am trying to get the reference of child component in promise function using component.find function I am unable to get it as find is not defined. I tried to get the same using component,get but still could not get the reference of child component. Below is the sample example of component I am using

//SampleDetails component

<aura:component controller="SampleController">

	<c:SampleInputLookup aura:id="SampleInputDropdown"
		dataOptions="{!v.SampleInputSS}" 
		valueField="description" 
		labelField="description" 
		title="SampleInput Sub Segment"                         
		onchange="{!c.sampleDropdownChange}"  
		opportuityAmount="{!v.opportuitySample}"/>
	
	<c:SampleInputLookup aura:id="SampleInputDropdown1"
		dataOptions="{!v.SampleInputSS1}" 
		valueField="description" 
		labelField="description" 
		title="SampleInput Sub Segment1"                         
		onchange="{!c.sampleDropdownChange1}"  
		opportuityAmount="{!v.opportuitySample}"/>

</aura:component>

testutil component destruction issue when API versions differ

cmp.destroy() fails in the clearRenderedTestComponents function if the targeted component is outside of the locker.

The workaround is simple. Inside of testutils change

if(status === "SUCCESS"){
    cmpsToCleanup.push(component.getGlobalId());
    if (renderInto) {

to

if(status === "SUCCESS"){
    if (renderInto) {
         var renderingContainer = $A.getComponent(renderInto);
         cmpsToCleanup.push(renderingContainer.getGlobalId());

then below in the clearRenderedTestComponents

while (cmpsToCleanup.length) {
        var globalId = cmpsToCleanup.shift();
        var cmp = $A.getComponent(globalId);
        cmp.set('v.body', []);
}

There is a scenario where the component is created and fails to be set to the renderInto body that needs to be handled, but this works quick and dirty.

Cannot test clicking of elements in component

I'm trying to write a test that verifies the correct value displays after a Lightning:button is clicked. Here are the problems:

  1. There is no click() method in the aura api. So if I use component.find(), there is no way I can invoke a click action on the button to invoke the function in my controller.

  2. I also tried using vanilla js, eg document.getElementById("someId"), but because of Locker Service that returns a Proxy object and I still can't call click() on the element.

In the examples in the test suite in this project, methods from the controller are exposed in the component, which we don't wish to do. We also have a lot of picklists we would like to set without creating a bunch of aura attributes that we don't need to actually make our component work.

I tried switching to an older version of the aura API for my component and test app, but that still did not work.

Is there a work around for being able to click/interact with elements on the component/DOM?

how to tests when v.body is set

I have a function that generates a component and puts it in the body of the component.

    generateOrderForm: function(component, orderInvite) {
        $A.createComponent(
            "c:shippingAddressUpdateForm",
            {
                "aura:id": "form",
                "orderInvite": orderInvite
            },
            function(form, status, errorMessage){
                if (status === "SUCCESS") {
                    var body = component.get("v.body");
                    body.push(form);
                    component.set("v.body", body);

                    // logs true
                    console.log(component.get("v.body").length == 1);
                }
                else if (status === "ERROR") {
                        console.log("Error: " + errorMessage);
                }
            }
        );         
    }

generateOrderForm() is called on init.

My test code

    describe('c:pageContainer', function(){     
        it('determine whether to show the shipping address form or an error message based on code in url', function(done) {

            // Setup
            spyOn($A, "enqueueAction").and.callFake(function(action) {
                var cb = action.getCallback("SUCCESS")

                var orderInvite = {"Id": "a0Ff0000003FIUEEA4"};

                cb.fn.apply(cb.s, [{ getState : function(){ return "SUCCESS"; }, 
                                        getReturnValue: function(){ return orderInvite;} 
                                    }]
                            );
            }); 
                        
            $T.createComponent("c:pageContainer", {}, true)
            .then(function(component){  
                // fails
                expect(component.get("v.body").length).toBe(1);
                done();

            }).catch(function(e) {
                done.fail(e);
            });
        });

The length of v.body is returning 0. What am I doing wrong?

How to test behavior dependent on afterScriptsLoaded

Apologies in advance for the wordy post but I wanted to provide enough context. I've posted this as a question on StackExchange but haven't gotten any response there, so forgive me for repeating it here, but I'm having trouble finding enough examples of LTS use cases to help me figure this out. This is also somewhat related to Keith's question in #54 ...

I’m looking for help/examples for setting up tests of a component which calls a load() method via afterScriptsLoaded, then renders data based on the result of the load (which calls a server-side controller) — something like this:

Component

<ltng:require scripts="{!join(',',$Resource.Constants,$Resource.Utils)}" afterScriptsLoaded="{!c.load}"/>

<aura:attribute name="currencyOptions" type="OppActionOverrideController.CurrencyOption[]" description="List of currency options with user's preferred currency set to default"/>
<aura:attribute name="someOtherThing" type="String" description="This is just an example of something else to render"/>

<aura:attribute name="showCurrencyField" type="Boolean" default="false" description="Value set in the load() callback"/>
<aura:attribute name="showSomeOtherField" type="Boolean" default="false" description="Value set in the load() callback"/>

<div class="slds-grid slds-wrap">
    ....
    <aura:if isTrue="{!v.showCurrencyField}">
    <div class="slds-form-element">
        <ui:inputSelect aura:id="selectedCurrency" label="Currency" required="true">
            <aura:iteration items="{!v.currencyOptions}" var="curr">
                <ui:inputSelectOption text="{!curr.isoCode}" label="{!curr.isoCode}" value="{!curr.isDefault}"/>
            </aura:iteration>
        </ui:inputSelect>
    </div>
    </aura:if>

    <aura:if isTrue="{!v.showSomeOtherField}">
        <div aura:id="someOtherField">foobar</div>
    </aura:if>
    ....
</div>

Controller

load: function (component, event, handler) {
    var action = component.get("c.getComponentData");
    action.setCallback(this, function(response) {
        // ....do some validation, if response is successful....
        // set up currency options
        component.set('v.showCurrencyField', true);
        component.set('v.currencyOptions', currencyOptions);

        // set other things
        component.set('v.showSomeOtherField', true);
        component.set('v.someOtherThing', 'hello');
    });
    $A.enqueueAction(action);
}

Test suite

afterEach(function() {
    $T.clearRenderedTestComponents();
});
describe("Rendering the component", function() {
    var getComponentDataPayload = {
        currencyOptions: [
            {isoCode: "USD", isDefault: true},
            {isoCode: "EUR", isDefault: false},
            {isoCode: "GBP", isDefault: false},
        ]
    };
    var renderedComponent = null;

    beforeEach(function(done) {
        renderedComponent = null;
		
        $T.createComponent("c:MyComponent", {}, true)
        .then(function(component) {
            // I assign the component to a separate var so that it can be referenced in specs below, allows me to use a beforeEach instead of having this code in every spec
            renderedComponent = component;

            spyOn($A, "enqueueAction").and.callFake(function(action) {
                var callback = action.getCallback("SUCCESS");
                // The utility function here just takes the payload data and wraps it with the proper getState() and getReturnValue(), etc.
                callback.fn.apply(callback.s, [TestUtils.getMockedServerActionResult(true, "", getComponentDataPayload)]);
                done();
            });
        }).catch(funtion(e) {
            done.fail(e);
        });
    });

    it("renders the currency options", function(done) {
        expect(renderedComponent.find("selectedCurrency")).toBeDefined();
        done();
    });

    it("renders some other field", function(done) {
        expect(renderedComponent.find("someOtherField")).toBeDefined();
        done();
    });
});

The specific problem I’m struggling with is where to place the spyOn (either inside the createComponent callback as above, or before it, or elsewhere) and also where to call done() in the beforeEach. The way the example is defined above, the first spec passes. But when the second spec runs, the scripts are already loaded, so that load() call happens immediately, before the createComponent callback happens (and so the spy is not registered and the done() function inside it is never called). I’ve tried moving the spy outside of the createComponent callback and calling done() in different places, but each results in a condition where either the renderedComponent var is not defined by the time done() is called (and thus the specs fail) or the done() method is never called due to the order that things execute the second time through and I get a timeout.

Is there a better way to structure this spec so that the order of the load call in relation to when the component is done rendering can be more predictable? I prefer to keep my it blocks simple and re-render the component each time, and re-rendering the component with different data to test conditional display is required for this test.

UPDATE
After experimenting a bit more I've tried modifying the structure of the beforeEach to this:

beforeEach(function(done) {
	renderedComponent = null;

	spyOn($A, "enqueueAction").and.callFake(function(action) {
		var callback = action.getCallback("SUCCESS");
		// The utility function here just takes the payload data and wraps it with the proper getState() and getReturnValue(), etc.
    	callback.fn.apply(callback.s, [TestUtils.getMockedServerActionResult(true, "", getComponentDataPayload)]);
	});

	$T.createComponent("c:MyComponent", {}, true)
	.then(function(component) {
		// I assign the component to a separate var so that it can be referenced in specs below, allows me to use a beforeEach instead of having this code in every spec
		renderedComponent = component;

		return $T.waitFor(function() {
			return renderedComponent.find("selectedCurrency") !== undefined;
		});
	}).then(function() {
		done();
	}).catch(function(e) {
		done.fail(e);
	});
});

To summarize the difference from the above version, this moves registering the spy out of the createComponent callback, which ensures it always happens. Then I am using a bit of a hack with waitFor to make sure the pieces of the component under test have indeed been rendered before testing them. This seems to result in a consistent order of operations, but now I am seeing timeouts (using the LTS-defined 3s) with the $T.createComponent, but only when running three or more specs. The first two specs run quickly and without a problem.

I'm hoping that I'm missing something obvious with this setup, does anyone have any ideas or examples of doing something similar?

jasmineTests.app not working

Hi,

Recently installed lightning test service and I'm getting the error attached when I attempt to run jasmine test app. I was able to run the mocha tests without any issues, so I'm not sure sure what's wrong.

screen shot 2018-08-06 at 11 24 35 am

Thanks,

Adding a waitForAura mechanism?

Still new to LTS, but finding $T.waitFor pretty annoying in that the condition that you want to expect on ends up in there or ends up being duplicated. Can you comment on the possibility of adding an API to the core Aura libraries of this nature (that is then exposed in LTS):

On top of this, Protractor automatically applies browser.waitForAngular() before every action to wait for all Angular $http and $timeout calls to finish. This allows developers to write the test scripts without much dread "callback hell," for the most part.

so that cleaner tests can be written?

test an init function

it would be nice if there was an example how to test an init function on a lightning component. I didn't see any of the sample components had init being using.

Question on `sfdx force:lightning:test:install -t jasmine`

I was curious if it is expected that sfdx force:lightning:test:install -t jasmine is run for each CI job? I ask this because after running sfdx force:lightning:test:install -t jasmine I then ran sfdx force:source:pull, expecting to see the Jasmine test runner component show up in my local project, so that I could check it into my project's SCM. Unfortunately that source code was not pulled.

I'm still getting used to SFDX's project structure, and from what I can tell, I cannot use my Force.com IDE plugin for Eclipse to connect to this scratch org (am I wrong there?) to pull the source.

Thanks for any insights!

-Tim

chain spyOn?

When my component loads, I make multiple calls to the server. I'm not sure how to test this. The server calls are as follows:

c:pageContainer -> getOrderInvite()

getOrderInvite() then loads the component

c:shippingAddressUpdateForm -> getShippingDestinationList()

getShippingDestinationList() -> getCountryStatePicklistValues()

So three server calls are enqueued in a chain when my app loads: getOrderInvite() -> getShippingDestinationList() -> getCountryStatePicklistValues()

This is my attempt on chaining spyOn, but it doesn't appear to work.

    describe('c:pageContainer', function(){     
        it('should show the shipping address form', function(done) {
            $T.createComponent("c:pageContainer", {code: "S3UYMUTY"}, true)
            .then(function(component){ 

                var orderInvite = {
                    "Id": "a0Ff0000003FIUEEA4",
                    "Account__c": "001f000000naH9iAAE",
                    "Order_Code__c": "S3UYMUTY",
                    "Order__c": "a09f0000003Bm2jAAC",
                    "Account__r": {
                        "Order_Pickup__c": true,
                        "Id": "001f000000naH9iAAE"
                    },
                    "Order__r": {
                        "Shipping_First_Name__c": "Tyler",
                        "Shipping_Name__c": "Zikaa",
                        "Shipping_Company__c": "55 Degrees",
                        "Shipping_Country__c": "United States of America",
                        "Shipping_State__c": "Alaska",
                        "Shipping_Address__c": "1210 Church St.",
                        "Shipping_City__c": "St. Helena",
                        "Shipping_Phone__c": "7079635513",
                        "Shipping_Zip_Postal__c": "39232",
                        "Status__c": "Complete",
                        "Shipping_Sent__c": true,
                        "No_Wooden_Box__c": true,
                        "Pickup__c": false,
                        "Id": "a09f0000003Bm2jAAC"
                    }
                };

                var res = {getState : function(){return "SUCCESS";}, getReturnValue: function(){return orderInvite;}};
                spyOn($A, "enqueueAction").and.callFake(function(action1) {
                    var cb = action1.getCallback("SUCCESS")
                    cb.fn.apply(cb.s, [res]);

                    var shippingDestinationList = [
                        {
                          "disabled": false,
                          "escapeItem": false,
                          "label": "55 Degrees",
                          "selected": false,
                          "value": "a0Bf00000036M36EAE"
                        },
                        {
                          "disabled": false,
                          "escapeItem": false,
                          "label": "Pickup/Local Delivery",
                          "selected": false,
                          "value": "1"
                        },
                        {
                          "disabled": false,
                          "escapeItem": false,
                          "label": "Ship To Address Below",
                          "selected": true,
                          "value": "0"
                        }
                      ]
                    var res = {getState : function(){return "SUCCESS";}, getReturnValue: function(){return shippingDestinationList;}};
                    spyOn($A, "enqueueAction").and.callFake(function(action2) {
                        var cb = action2.getCallback("SUCCESS")
                        cb.fn.apply(cb.s, [res]);
                        
                        var countryStateListOptions = {
                            "Czech Republic": [
                              {
                                "disabled": false,
                                "escapeItem": false,
                                "label": "Outside US",
                                "selected": false,
                                "value": "Outside US"
                              }
                            ],
                            "Canada": [
                              {
                                "disabled": false,
                                "escapeItem": false,
                                "label": "Alberta",
                                "selected": false,
                                "value": "Alberta"
                              }
                            ],
                            "United States of America": [
                              {
                                "disabled": false,
                                "escapeItem": false,
                                "label": "Alabama",
                                "selected": false,
                                "value": "Alabama"
                              },
                              {
                                "disabled": false,
                                "escapeItem": false,
                                "label": "California",
                                "selected": true,
                                "value": "California"
                              },
                              {
                                "disabled": false,
                                "escapeItem": false,
                                "label": "Oregon",
                                "selected": false,
                                "value": "Oregon"
                              },
                              {
                                "disabled": false,
                                "escapeItem": false,
                                "label": "Alaska",
                                "selected": false,
                                "value": "Alaska"
                              }
                            ]
                          }
                        var res = {getState : function(){return "SUCCESS";}, getReturnValue: function(){return countryStateListOptions;}};
                        spyOn($A, "enqueueAction").and.callFake(function(action3) {
                            var cb = action3.getCallback("SUCCESS")
                            cb.fn.apply(cb.s, [res]);
                        }); 
                    }); 

                });    
                return $T.waitFor(function(){
                    return component.get("v.body").length === 1;
                })
            }).then(function() {
                expect(component.get("v.body").length).toBe(1);                
                done();
            }).catch(function(e) {
                done.fail(e);
            });              
        });
    });

All these server calls need to happen in order to load c:shippingAddressUpdateForm into the v.body of c:pageContainer, which is what I'm testing for.

I'm currently getting

Error: Error in $A.getCallback() [Cannot read property 'getState' of undefined]
so the server response.getState() isn't being set properly in my chain.

How to interact with the custom components using LTS ?

For Example I am having component c:uiInputText which has a attribute "property". My custom component extends SFDC lightning component ui:inputText and I will set the value attribute via the property attribute my custom component.

Now when I tried to set the value for the custom component, I am not able to set and also I am not seeing any error. Any idea would be great

Sample snippet:

var ruleNameCMP = component.find("ruleid");
ruleNameCMP.set("v.property","value 1"));

saucelabs environment vars

Hi,

I am trying to connect LTS with saucelabs.com, and I has successfully connected with this command:

sfdx force:lightning:test:run -f config.json

And the following configuration in config.json

{
  "webdriverio": {
    "host": "ondemand.saucelabs.com",
    "port": "80",
    "user": "saucelabs_user",
    "key": "secretkey",
    "desiredCapabilities": {
      "browserName": "chrome",
      "chromeOption": {
        "args": [ "--no-sandbox" ]
      }
    }
  }
}

This run :)

But the question is:

Can I use two environment variables instead of push these secrets to the git repository?

This is a Best Practices and it is very interesting for continuous integration environment.

Sample:

export SAUCE_USERNAME=saucelabs_user
export SAUCE_ACCESS_KEY=secretkey
sfdx force:lightning:test:run -f config.json

Thanks.

How to mock Server actions with spyOn for doInit()

I am trying to test a component with server actions call during doInit(). This is my spec:

describe('c:myComponent', function(){  
    it('renders stuff as expected', function(done) {
        $T.createComponent("c:myComponent", {}, document.getElementById("renderTestComponents"))
            .then(function(component) {
                // Setup
                spyOn($A, "enqueueAction").and.callFake(function(action) {
                    var cb = action.getCallback("SUCCESS")
                    cb.fn.apply(cb.s, [{ getState : function(){ return "SUCCESS"; }, 
                                            getReturnValue: function(){ return "a0DC000000vc03tMAA";} 
                                        }]
                                );
                });
            })
            // Verify
            .then(function(component) {
                expect(component.get("v.accounts").length).toBe(2);
                done();
            })
            .catch(function(e) {
                done.fail(e);
            });
    });
});

I am testing a component where doInit() uses Promises:

doInit: function(cmp, event, helper) {
   helper.callServer(cmp);
}

to call 2 helper methods which call server actions

callServer: function(cmp) {
		var action = cmp.get("c.serverAction");
action.setCallback(this, function(response) {
            cmp.set("v.accounts", response.getReturnValue());
        });
        $A.enqueueAction(action);
    }

I get obscure JS errors, so I thought maybe this is not the right way to do it. Can you provide an example on how to mock/stub initialisation?

ERROR: Cannot read property 'endsWith' of undefined.

I am getting ERROR: Cannot read property 'endsWith' of undefined. when running sfdx force:lightning:test:run -a jasmineTests.app after upgrading to the GA release of sfdx.

Any ideas on what is going sideways?

Build error: plugin salesforcedx is not digitally signed

While building my CI with Travis I got an error while installing Salesforce DX and I just noticed that this repository is also impacted by it (build is failing at time of writing).

When running sfdx plugins:install salesforcedxthe CLI will output a blocking prompt which breaks CI:

Installing plugin salesforcedx... Checking for digital signature.
This plugin is not digitally signed and its authenticity cannot be verified. Continue installation y/n?: 

I am bit surprised that this official plugin is not signed so perhaps it's a bug in the plugin build chain.

Here is how I fixed it based on the official DX doc:

  1. Create a plugin whitelist file named unsignedPluginWhiteList.json in the config directory with the following content:
[
    "salesforcedx"
]
  1. Move the whitelist file in a specific directory before running the plugin install command:
    mv config/unsignedPluginWhiteList.json $HOME/.config/sfdx/.

I hope that it helps.

lightning:input.showHelpMessageIfInvalid runtime error

I don't think these is the right place to post this, but running my tests I step in this problem:

Action failed: lightning:input$controller$showHelpMessageIfInvalid [Unable to get property 'validity' of undefined or null reference]

In the test case I set an object to my component, that is binded with a list of lightning:input by value property:

<lightning:input aura:id="fields" name="name" required="true" label="Name" value="{!v.account.Name}" />

then I fire the press event on my save button that, in the end, call

let allValid = cmp.find('fields').reduce((acc, el) => {
el.showHelpMessageIfInvalid();
return acc && el.get('v.validity').valid;
}, true);

and so I get the runtime error.

GAC when testing scenario 2

I am following the tutorial from the sfdx blog and am stuck on Scenario 2.

I'm having trouble completing scenario 2, Verify data binding, and I get an error that says Failed: An internal server error has occured. From modifying the code, it looks like it's breaking when trying to create the component c:componentWithDataBinding. Specifically when calling the $T.createComponent('c:componentWithDataBinding') function in the jasmine test.

I've tried creatting a new scratch org and got the same error. I've also tried to create a new component and copy&pasted the examples but can't figure out why the createComponent is not working for me.

I have an example of my code in a gh repo here. I am able to recreate the issue by:

  1. Created a DevHub org (not required) or use existing one.
  2. git clone https://github.com/joseph-ortiz/lightning-testing-service-demo
  3. cd lightning-testing-service-demo
  4. sfdx force:org:create -f config/project-scratch-def.json -a lts
  5. sfdx force:lightning:test:install -u lts
  6. sfdx force:source:push -u lts
  7. sfdx force:org:open -u lts -p /c/myTestApp.app
  8. see GAC error.

screen shot 2018-04-18 at 5 16 15 pm

https://developer.salesforce.com/blogs/2018/04/getting-started-with-the-lightning-testing-service.html

prerequisites to write tests?

Writing tests for my Lightning Components has been a frustrating and difficult experience. I'm not sure what the disconnect is. I'm Platform II certified, can write apex tests no problem, have put a lightning component app that is lightning ready on the app exchange, and have coded react and angular js app that are hosted in Salesforce.

What are the perquisites to write tests?

What books of JavaScript would you recommend? Writing js for lighting componets feels very different to writing js with react/angular for me.

Unable to handle lightning:tab components

We have referred the workaround suggested for lightning buttons and tried up with aura:method to expose the controller actions. Now we have a case where we dont have logic defined in controller actions. Necessary items where defined in the lightning:tab itself.need to switch between the tabs.
sample snippet :

<lightning:tabset>
            <lightning:tab label="label1">
             </lightning:tab>
 <lightning:tab label="label2">
             </lightning:tab>
 </lightning:tabset>

Can you please suggest some workaround to handle the lightning:tab ?

Lightning Test Context

It's not clear to me if the lightning tests run in a test context like the Apex unit tests do. By this I mean are any changes made to the database from the front end are rolled back rather than committed.

I wouldn't expect to be writing tests that have these kind of side effects, but there's always the chance that code changes underneath my tests and suddenly something that was locally cached is persisted.

How does SFDX get the test results?

I've written a couple of custom reporters for Salesforce/Lightning/Jasmine which I'd like to port over to LTS and integrate with SFDX. Are you able to share how the SFDX CLI gets the test results when executing "sfdx force:lightning:test:run" - e.g. is it a screen scrape or does something get inserted etc. Thanks.

Capturing showToast events

I have some logic that display showToast event for success && failure. I'd love to catch those events and so I can validate code works correctly. Is there a way to catch system events using testing service?

Alternatively, is there a Test.isRunningTest() method equivalent from Apex in LTS so I could create a workarounds for such cases as above?

Doc question: "test" folder behavior

Hi,

I have been looking at the documenation for the Salesforce DX project structure but I could not find anything regarding the test folder (lightning-component-tests/test/default in your repository).

I do not want to deploy my Lightning tests in production so should I use this folder in combination with the main directory like you did? I am also Java dev so this project structures means something for me but does it translate to DX?
You may want to document it if there are special rules for this folder.

Cheers,

Looking for reference about $T

Team,
I looked over the sample test resources and found $T namespace. Are there any reference about the methods in this namespace like $T.fireApplicationEvent? I would like to know what and how to use those methods.

Unable to use LTS with SFDX

I'm following the instructions to connect LTS to SalesforceDX. Once I've updated the plugin to work with the beta (via sfdx plugins:install salesforcedx@pre-release) I get the following error when trying to create a scratch org:

ERROR running force:org:create: You do not have access to the [ScratchOrgInfo] object.

(I'm guessing this might be because scratch orgs get created on CS70 at present which is a Spring 17 org)

If I revert back to the latest stable plugin then I can create the scratch orgs, albeit at version 39.0, so I've been trying to get as far as I can switching between the stable and pre-release plugins.

If I try to push the source using the pre-release, I get the error "the requested resource does not exist". I can push the source using the stable version if I make a few changes to lower the API version in the Apex meta-xml and remove references to recordData. Once this is done I can execute the Tests.app, but if I switch back to the pre-release plugin to use the force:lightning:test:run, I get the following error:

ERROR running force:lightning:test:run: An error occurred when running Lightning tests. The requested resource does not exist.

Should the pre-release plugin be able to create scratch orgs at API 40.0? Feels like that might solve the problem.

API version for test components not on Winter '18

The API version of these components is not on Winter '18. With that they don't run in an org that makes use of Winter '18 components (i. e. accordion).

https://github.com/forcedotcom/LightningTestingService/tree/master/lightning-component-tests/test/default/aura

Seen because the installation of the package (via the sfdx cli) fails

1.  The API version of this bundle must be set to '41' or later to use component 'markup://lightning:accordion'
mochaTests: The API version of this bundle must be set to '41' or later to use component 'markup://lightning:accordion'

2.  The API version of this bundle must be set to '41' or later to use component 'markup://lightning:accordion'
lts_mochaRunner: The API version of this bundle must be set to '41' or later to use component 'markup://lightning:accordion'

3.  The API version of this bundle must be set to '41' or later to use component 'markup://lightning:accordion'
lts_jasmineRunner: The API version of this bundle must be set to '41' or later to use component 'markup://lightning:accordion'

4.  The API version of this bundle must be set to '41' or later to use component 'markup://lightning:accordion'
jasmineTests: The API version of this bundle must be set to '41' or later to use component 'markup://lightning:accordion'

Packaging with source:convert

When attempting to setup the project structure like the following:

force-app
├── main
│   └── default
│       ├── aura
│       │   ├── Search
│       │   │   ├── Search.cmp
│       │   │   ├── Search.cmp-meta.xml
│       │   │   ├── Search.css
│       │   │   ├── Search.scss
│       │   │   └── SearchController.js
└── test
    └── default
        ├── aura
        │   └── searchTests
        │       ├── searchTests.app
        │       ├── searchTests.app-meta.xml
        │       └── searchTests.auradoc
        └── staticresources
            ├── Search.resource
            ├── Search.resource-meta.xml
            ├── testHelpers.resource
            └── testHelpers.resource-meta.xml

Everything works great for running tests and pushing source like sfdx force:source:push

However, when I do sfdx force:source:convert, it includes the test path and all its pieces as well.

My sfdx-project.json looks like this:

{
  "packageDirectories": [
    {
      "path": "force-app",
      "default": true
    }
  ],
  "namespace": "",
  "sfdcLoginUrl": "https://login.salesforce.com",
  "sourceApiVersion": "41.0"
}

is there any way to continue including the test package for the sfdx force:source:push command but exclude it when running sfdx force:source:convert?

Test results in "junit" format from "sfdx force:lightning:test:run" present badly because the classname is set to an empty string

When Jenkins "Publish JUnit test result report" is setup for the output of "sfdx force:lightning:test:run" that is running LTS tests, the test results for passing tests are presented as a single line (with counts and times aggregated) instead of a line per test.

The XML output lines all have an empty string for their classname:

<testcase name="c:wizContainer : body component has been created" classname="" time="1.86"></testcase>

and the presentation code appears to group by that attribute.

This code appears to provide the values:

class LightningTestResults extends TestResults {
    constructor(testApi, tests, runResultSummaries, config) {
        super(testApi.testrunid, testApi.startTime, 'force.lightning', tests, runResultSummaries, config);
    }
    getTestContainerName() {
        return '';
    }
    getTestNamespace(test) {
        return test.NamespacePrefix;
    }
    getTestName(test) {
        return test.FullName;
    }
}

and this is the equivalent for Apex (for reference):

class ApexTestResults extends TestResults {
    constructor(testApi, tests, runResultSummaries, config) {
        super(testApi.testrunid, testApi.startTime, 'force.apex', tests, runResultSummaries, config);
    }
    getTestContainerName(test) {
        return test.ApexClass.Name;
    }
    getTestNamespace(test) {
        return test.ApexClass.NamespacePrefix;
    }
    getTestName(test) {
        return test.MethodName;
    }
}

with the XML built by:

            let classname = this.getTestContainerName(test);
            if (this.getTestNamespace(test)) {
                classname = this.getTestNamespace(test) + classname;
            }
            junit += `        <testcase name="${this.getTestName(test)}" classname="${classname}" time="${test.RunTime ? msToSeconds(test.RunTime) : 0}">\n`;

Changing LightningTestResults.getTestContainerName(test) to return the same thing as LightningTestResults.getTestName(test) would be a quick fix, but perhaps a better value could be returned.

(I realize this code isn't part of LTS but perhaps you can pass this on to the relevant team?)

Is there any way to locate the lightning components and trigger automated actions in it ?

We are trying hard to locate and handle the lightning components such as
lightning:button menu,
lightning:button Icon,
lightning:select,
lightning:tabs ,
lightning:layouts
and trigger automated actions in it.
When we try it from the DOM it says "undefined", we suspect that due to the locker services. Is there any way to handle these components. In this sample tests also we don't find any examples for these components locator also. Could any one please guide me on this ?

New jasmine suite not recognised

Hi there,

I'm having trouble getting a new suite to be recognised. Steps

  1. Downloaded the "Lightning Testing Service with Examples" package.
  2. Created the following javascript file

describe("Lightning Component Testing Examples", function(){
afterEach(function() {
// Each spec (test) renders its components into the same div,
// so we need to clear that div out at the end of each spec.
$T.clearRenderedTestComponents();
});

    describe('c:ContactCreatorL', function(){
    // We encourage you to have the code for c:egRenderElement side by side
    // when reading through this spec.
    it('creates a contact successfuly', function(done) {
        //instantiate the component using its name
		$T.createComponent("c:egComponentMethod", null)
        // The 'component' here is the instance of c:egRenderElement
        .then(function(component) {
            
        	var fakeResponse = {
				getState : function(){
					return "SUCCESS";
				}
			};

			//call the apexMethod function, which contains a reference to the apex controller
			spyOn($A, "enqueueAction").and.callFake(function(action) {
                var cb = action.getCallback("SUCCESS")
                cb.fn.apply(cb.s, [fakeResponse]);
            });

            expect(component.get("v.creationSucceded")).toBe(true);

            done();
        }).catch(function(e) {
            // end this spec as a failure
            done.fail(e);
        });
    });
});

});

  1. Went to the file > right click > compress > uploaded it as a static resource as application/zip
  2. Go to https://[myDomain]/c/jasmineTests.app and the test is not there.

The documentation doesn't say anything more than "uploaded the suite as a static resource", which I've done as per the above steps. The syntax appears to be correct and I'm not getting any errors or warnings.

Is there anything I need to do for this suite to be tested?

Testing with namespaces and Labels

I have been running into some weird issues regarding custom labels in javascript -> https://developer.salesforce.com/docs/atlas.en-us.lightning.meta/lightning/labels_dynamic.htm

Basically, everything seems to work fine for namespace in the regular application, but when I go to write tests, it seems there is some loading issues for the test framework. Namely, if I have a test like this:

it('should have the correct label', () => {
  const expectedLabel = $A.get('$Label.MyNamespace.MyLabel');
  expect(document.getElementsByClassName('myCssClassName')[0].textContent).to.equal(expectedLabel);
});

It works sometimes and other times it claims that expectedLabel is equal to '' (empty string)

Is there something I am missing about namespacing labels and how they are loaded?

How to mock or configure lightning:workspaceAPI in tests?

I have a Lightning Component that uses the lightning:workspaceAPI component to detect that it is (or is not) running in the console view. I'm starting to look at setting up some LTS tests and am wondering what can be done to either mock or configure so that the lightning:workspaceAPI calls work?

The methods I'm using are:

  • isConsoleNavigation
  • getEnclosingTabId
  • getFocusedTabInfo

and I want tests for both console view and non-console view.

(Nothing came back on this for this https://salesforce.stackexchange.com question).

Accessing inherited component

I'm testing a component that manages a date input field, which extends a base input component that handles the common aspects of an input, so label, error display etc. My initial test was simply to verify that the label I'd passed the component on creation was being applied correctly.

The label is a regular HTML element, with an aura:id to make it accessible from the component, and is present in the base component.

I've followed the approach in the examples and dynamically created the date component, but when I try to verify the label, component.find() always returns null. If I move the label into the date component, the find() works correctly and retrieves the label.

Initially I thought this might be down to the locker service (although I'd expect to be able to access everything in my namespace), but having downgraded all components to API 39 I still see the same behaviour.

Is there something around the way that components are created for testing that isolates them from even the base components that they extend?

Overlapping of rendered components with the App Components

In LTS Examples, we are using the custom component "lts_jasmineRunner.cmp". In my case when we tuned as per my requirement (For Example. we tried by including the necessary scripts and jasmine libraries as in the custom component "lts_jasmineRunner" in my App) , The problem was that we are facing overlapping between the rendered component and the App Components.

We suspect that the Rendering component in the div element might causing the collision with the App components. Could you please help on getting this resolved ?

sfdx force:lightning:test:install fails with "Cannot read property 'indexOf' of undefined"

I've been seeing this error more frequently lately:

$ sfdx force:lightning:test:install -u my_org

fails with

  ▸    Cannot read property 'indexOf' of undefined

I know it is a problem with the CLI, but this was intermittent and becoming more of a burden during CI testing (it will pass 1/10 times now)

Are there any suggestions on things like waiting time, retry logic, etc. after creating a new scratch org that I can employ in order to reduce the times this install fails?

Any help is greatly appreciated

Executing force:lightning:test:run from Docker container results in Unknown Error (13)

I'm currently getting bitbucket pipelines set up and running in a CD environment, and using LightningTestService to run lightning component tests. Bitbucket pipelines runs in a docker container.

My script fails at the following:

sfdx force:lightning:test:run -a jasmineTests.app
Waiting to resolve the Lightning Experience-enabled custom domain........
ERROR running force:lightning:test:run: An error occurred when running Lightning tests. An unknown server-side error occurred while processing the command. (UnknownError:13)

I'm using the default jasmineTests.app that comes with the "LTSExamples" package, and when I issue that same command from my local machine, it works fine.

Is it possible that since the script requires a browser to open, that this won't work from a "headless flow" or container?

Sleep utility function

It would be useful to have a sleep type function in the $T namespace. For example, I have moved some singleton functionality into a JavaScript library that my components load via ltng:require and they defer their initialisation until that script is loaded. In the case of unit tests I just want to sleep for a couple of seconds to allow the library to load and then carry out the tests.

I don't want to artificially set an attribute or the like just to be able to use waitFor, and given that my lightning component might be running at a different API version to the baseTestRunner component I can't guarantee that I can load it there and attach it to the correct Window/SecureWindow object.

I've written my own, obviously, but not the most efficient if everyone has to do that going forward :)

$T namespace documentation

Is there any documentation on the functions available in the $T namespace? I can figure out what is in the examples, but curious as to whether there are any nuances (e.g. does $T.waitFor() have a configurable timeout) or additional methods that don't appear in the examples.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.