forcedotcom / lightningtestingservice Goto Github PK
View Code? Open in Web Editor NEWLicense: Apache License 2.0
License: Apache License 2.0
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 serverresponse.getState()
isn't being set properly in my chain.
Hi there,
I'm having trouble getting a new suite to be recognised. Steps
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);
});
});
});
});
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?
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 ?
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?
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?)
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 :)
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:
In master branch, lts_testutil.resource, line 170 declares failureMessage.
The same file (line 162) in the package does not, which prevents the tests from running correctly.
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.
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?
I'm trying to write a test that verifies the correct value displays after a Lightning:button is clicked. Here are the problems:
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.
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?
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,
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:
and I want tests for both console view and non-console view.
(Nothing came back on this for this https://salesforce.stackexchange.com question).
run this command with sfdx-cli/6.0.16-3780698 (darwin-x64) node-v8.6.0
sfdx force:lightning:test:run
ERROR: Cannot read property 'endsWith' of undefined.
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?
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.
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.
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?
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>
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.
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?
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.
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.
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.
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
?
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
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.
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?
I need to find if a
How else do I do such tests?
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).
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'
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
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)
When downloading the unmanaged package for Jasmine (without examples - the first URL here https://github.com/forcedotcom/LightningTestingService/releases), the lightning app to run the jasmine tests is missing i.e https://{mydomain}/c/jasmineTests.app
If I install the unmanaged package with examples, then the app is there. Is this expected or am I supposed to somehow create my own app using the Jasmine source files?
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.
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?
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 salesforcedx
the 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:
unsignedPluginWhiteList.json
in the config
directory with the following content:[
"salesforcedx"
]
mv config/unsignedPluginWhiteList.json $HOME/.config/sfdx/.
I hope that it helps.
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
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.
Trying to install the unmanaged package from this url:
https://test.salesforce.com/packaging/installPackage.apexp?p0=04tJ00000006jBu
It's not accepting my org's username/password.
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 ?
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.
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?
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 ?
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"));
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.
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?
Is there a way to test a method that is not exposed through the component's public interface ? We may have some methods that need to be tested, but that we don't want to expose.
In exempleTests it seems that all methods are called via an aura:method
in the related component.
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
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?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.