how to invoke or get the sub-property value from Properties Tab in cypress - cypress

How to invoke the sub-property value from the properties tab. I need to get the value of the error.JPG in from Properties Tab
I tried with these different codes changes
cy.get('div [data-text-as-pseudo-element="error.JPG"]').invoke('prop','dataset').should('contain','error.JPG')
cy.get('div [data-text-as-pseudo-element="error.JPG"]').invoke('prop','dataset').should('contain','DOMStringMap')
cy.get('[data-text-as-pseudo-element="error.JPG"]').invoke('prop', 'dataset').then(dataset,()=>{
cy.wrap(dataset).invoke('prop','textAsPseudoElement').should('contain','error.JPG')
})
I'm getting Assertion Error
Timed out retrying after 4000ms: object tested must be an array, a map, an object, a set, a string, or a weakset, but domstringmap given

From HTMLElement.dataset
The dataset read-only property of the HTMLElement interface provides read/write access to custom data attributes (data-*) on elements. It exposes a map of strings (DOMStringMap) with an entry for each data-* attribute.
Your Cypress test can just treat it as a conventional attribute
cy.get('my-selector')
.should('have.attr', 'data-text-as-pseudo-element', 'error.JPG')
The tests you propose above are already complete with just this
cy.get('div[data-text-as-pseudo-element="error.JPG"]')
because the browser guarantees the attribute will be added to dataset.
If you want to work further with dataset in Javascript just chain the properties, e.g
cy.get('div[data-text-as-pseudo-element="error.JPG"]')
.should($el => {
const attrValue = $el[0].dataset.textAsPseudoElement
expect(attrValue).to.eq('error.JPG')
})

Related

How to query data-attribute for a whitespace-separated value in Cypress component tests?

When testing a complex component, I want to assign multiple whitespace-separated values to data-cy attribute, for example
<div data-cy="my-component disabled" />
and use the ~= attribute selector to query for the element:
cy.get('[data-cy~="my-component"]')
Now, having already queried for my-component, how can I further assert that it:
does contain "disabled" in data-cy
does not contain "disabled" in data-cy
in broader sense, does or does not satisfy a css selector?
I know I can explicitly re-query with all parameters for each assertion, eg.:
cy.get('[data-cy~="my-component"]:not([data-cy~="disabled"])').should('exist')
but this feels overly complicated and doesn't read very well - I want to query the element first, and further assert against it in a later step - for example:
cy.get('...').should(el => {
// assert here
})
The approach seems like a good one. If you used individual attributes, likely they would clash with other "native" attributes.
For example if data-cy="disabled" means the "Person" has a disability, but used unwrapped the browser would disable the element.
Ref Using data attributes
data-* attributes allow us to store extra information on standard, semantic HTML elements without other hacks such as non-standard attributes, or extra properties on DOM.
Also some frameworks (React) are fussy about the attributes allowed on an element.
You might be looking for a function to provide the selector for the test.
const asDataCy = (attrs) => {
return attrs.split(' ').map(attr => {
let op = '~'
if (item.charAt(0) === '!') {
op = '!'
attr = attr.slice(1)
}
return `[data-cy${op}="${attr}"]`
).join('')
}
cy.get(asDataCy('my-component !disabled'))
// [data-cy~="my-component"][data-cy!="disabled"])
The Chai-jQuery assertion expect($el).match(selector) does exactly that!
// should form
cy.get('[data-cy~="my-component"]')
.should('match', '[data-cy~="some-value"]')
.should('match', ':not([data-cy~="something-else"])')
// expect form
cy.get('[data-cy~="my-component"]')
.then(el => expect(el).to.match('[data-cy~="some-value"]'))
.then(el => expect(el).to.match(':not([data-cy~="something-else"])'))

Cypress, how to check for text typed into a field?

I can verify text appears "somewhere" on the results page with
it.only('can verify an input element has certain text typed into it', function() {
cy.visit('http://google.com')
cy.get("input[name=q]").type('abc123{enter}') // with or without the {enter}
cy.contains('abc123') // Anywhere on the page :(
})
but how can I verify the text I type in the input text box?
I tried chaining to the element with
it.only('can verify an input element has certain text typed into it', function() {
cy.visit('http://google.com')
cy.get("input[name=q]").type('abc123{enter}')
cy.get("input[name=q]").contains('abc123')
})
but I get
CypressError: Timed out retrying: Expected to find content: 'abc123' within the element: <input.gLFyf.gsfi> but never did.
I tried cy.get("input[name=q]").contains('abc123') and
cy.contains('input[name=q]', 'abc123')
but both time out and fail.
Change .contains to use .should('have.value'...
cy.get("input[name=q]").type('abc123{enter}')
cy.get("input[name=q]").should('have.value', 'abc123')
You may not like this idea but here is just a suggestion so you don't have to keep calling cy.get each time.
You could always set a const value for your input name (could be in an external file) so:
export const inputField = () => cy.get('input[name=q]');
This will do the get whenever you call inputField.
so then your call would be:
inputField.type('abc123{enter}').should('have.value', 'abc123');
Thats just more a setup thing than an actual soluton, as I know you solved the issue yourself, but the above is quite a nice way so you don't have to keep doing cy.get on the same field.
Instead of using contains, you can read the text you already entered in the input field using "then()". Here's how:
cy.get("input[name=q]").type('abc123').then(function($input){ const value = $input.text() expect(value.includes('abc123')).to.be.true })

how to add threshhold value in the QnA maker if it being called using the QnAMakerRecognizer.recognize method

I replaced my code where I was making a QnA dialog using new cognitiveservices.QnAMakerDialog constructor and I was able to pass extra key-value pair for example threshold, feedbackLib etc. with the code where I can use QnA in single dialog using
cognitiveservices.QnAMakerRecognizer.recognize(query, 'QnAhost', 'endpointKey key','Authorization', 3, 'intentname', function (error, results) 
{
session.send(results.answers[0].answer); 
// console.log(results);
}); 
}).triggerAction({
matches: 'intentname'
});
But I am not sure how can I add the threshold value and feedbackLib to the QnA. This way it is returning an answer even if the confidence score is very low.
Please help.
Thanks.
Vivek,
the constructor for QnAMakerRecognizer takes a set of IQnAMakerOptions. These are defined here
When you create your recognizer instance call the contructor like this:
var recognizer = new cognitiveservices.QnAMakerRecognizer({
knowledgeBaseId: 'set your kbid here',
authKey: 'set your authorization key here',
qnaThreshold: (This is a number) set your threshold value here,
feedbackLib: (This is a QnAMakerTool object) set your lib here
});
Hope this helps.

Count how many errors with Ember-Validations?

I would like to display the count of validation errors to my user.
It is to implement a message like "You have X error(s) left" next to the submit button.
Is there a way to do this ?
Edit :
I am using ember-validations 2.0.0-alpha.1 and ember 1.8.0 in the context of a controller (without ember data).
If I try the solution of Sam:
this.get('errors.length') // result is [], an empty array
The errors key holds an object, not an array. Each key of this object refers to a property on your model and points to an array of error messages, so you can do things like this.get('errors.firstName.length').
To find the total number of errors, you'd have to look through each of your model's properties and sum the number of errors for each one.
http://emberjs.jsbin.com/luzesiyeqi/1/
EDIT:
The .length property of the errors object is returning an empty array because of this code: https://github.com/dockyard/ember-validations/blob/master/addon/errors.js. Literally any key you access on the errors object will be initialized to an empty array.
EDIT 2:
Based on what you said in the comments about not wanting to loop through properties, you can do it in an alternative fashion by looking at the model's validators property. Check out this example:
numErrors: function () {
var errorCounts = this.get('model.validators').mapBy('errors.length');
return errorCounts.reduce(function (a, b) { return a + b }, 0);
}.property('model.validators.#each.length')
I've updated the JSBin, too:
http://emberjs.jsbin.com/jucuxodaga/1/edit?html,js,output
If you're using ember-validations, this will be easy: this.errors.length.

jsPlumb deleting element's connections

I'm working on a jsPlumb problem. When I try to programatically remove all of an elements connections, I get Uncaught TypeError: Cannot read property 'left' of undefined
I have several "nodes" (html elements) that each have 1 input endpoint (an end point that accepts) and n output endpoints. Each node also has a javascript object behind it. I have a "selected" state in my software. Users can select multiple nodes and the objects are pushed to an array called selected. I have a key listener for the delete key. When the key is pressed it loops through selected nodes, deleting them and removing their endpoints. This works great when there are no connections, but when there are connections I the error.
The output endpoints are attached to child HTML elements of the main node…
There's a lot of code doing lots of stuff, but I'll try to share the relevant parts:
function Node(jsonFromServer){
/* … this is the constructor method… some code omitted*/
this.endpoints = [];
this.endpoints.push(jsPlumb.addEndpoint(this.el.attr("id"),targetEndpoint,{anchor:"TopCenter",uuid: this.el.attr("id") + "TopCenter"}));
this.addConnectionEndpoints();
}
Node.prototype.addConnectionEndPoints = function(){
//omitting code… loops through 'connections' that don't have 'has endpoint' marked….
this.endpoints.push(jsPlumb.addEndpoint(connection['el'].attr("id"),sourceEndpoint,{anchor:"RightMiddle",uuid:connection['el'].attr("id")+"RightMiddle"}));
connection.hasEndPoint = true;
}
So that was the setup. Here's how I delete
when key pressed
If key is delete /* all this stuff works */
loop through selected array (the array of selected Node elements:works)
node.el.hide(250).remove();
loop through node's endpoints array
//endpoint is the correct object... proved with console.log
//the following line is the error
jsPlumb.deleteEndpoint(endpoint);
ajax call to server to delete stuff on the backend
Fixed it! When I said node.el.hide(250).remove(); I removed an html element that was required in the delete process. I moved the remove part to the callback of the ajax request, and it works like a charm.

Resources