Debug value of Selector - debugging

Maybe a simple question but I completely fail to solve it myself.
How to debug/output the value of a selector?
await t
.expect(Selector('.progress-bar.progress-bar-success').getStyleProperty('width')).eql('100%', {timeout: 90000})
I tried to use
console.log(Selector('.progress-bar.progress-bar-success').getStyleProperty('width'));
and also with .value at the end. But I do not get any information.
Is any tip available?

Selector returns a Promise. You need to wait until the promise was resolved. To do this, just add the await keyword before the Selector call.
console.log(await Selector('.progress-bar.progress-bar-success').getStyleProperty('width'));

Related

Rxjs await Observable complete

I’d like to await the completion of my observable. It has a takeUntil I receive a value emited from my cancel$ observable. Its possible that cancel$ emits a valeu befor observable1 even emits its first value. That will give me an error.
await lastValueFrom(observable1.pipe(takeUntil(cancel$)))
console.log("myObservable is completed");
I found that using the deprecated await observable1.toPromise() fixes my problem. But I'd like to avoid something deprecated.
Ok, I finally found my answer here : .toPromise() and lastValueFrom() in rxjs
lastValueFrom takes a second parameter where you can define a default value when nothing has been emitted.

How do i clear a multi-select input using Cypress?

How do i clear (deselect) all options within a multi-select input using Cypress?
The documentation here does not seem to cover this scenario: https://docs.cypress.io/api/commands/select.html#Syntax
The clear() command apparently cannot be applied to selects, as you might expect
https://docs.cypress.io/api/commands/clear.html#Syntax
I have tried passing an empty string / array / null to select() but i get the following error:
CypressError: Timed out retrying: cy.select() failed because it could not find a single <option> with value or text matching: ''
Since Cypress 8.6.0, this is supported in Cypress: https://stackoverflow.com/a/69537449/3474615
Before 8.6.0:
You can use cy.invoke() to call the .val('') method on the underlying JQuery element, which will cause it to be cleared.
Like this:
cy.get('select')
.invoke('val', '')
Note that this will not emit the change event. If you want to test that your code reacts to the change event, you can cause it to be emitted with cy.trigger():
cy.get('select')
.invoke('val', '')
.trigger('change')
I've also filed a feature request for this functionality, as it does seem like something that should be included with Cypress by default.
cy.select([])
cy.select([]) called with an empty array, can now be used to clear selections on all options.
Note: update cypress to v8.6.0 or higher to work.

Protractor, do I have to use then() after protractor calls?

Is it ok to write:
getFieldX().clear().sendKeys('abc');
or should I write:
getFieldX().clear().then( () => sendKeys('abc));
I'm totally confused about the Promise handling in protractor. clear() returns a promise, so I should use .then() afterwards, shouldn't I?
But I found examples with .then and some without.
Protractor itself has an example without .then():
https://www.protractortest.org/#/control-flow
Does Protractor has its own mechanism and resolves one after the other promise so there is no need for using .then() after a protractor call that returns a Promise?
And is the control flow of protractor only active in a spec?
When using .sendKeys() in a normal function I have to use .sendKeys().then(...) ?
This all depends on if you are using SELENIUM_PROMISE_MANAGER or not. As this is (has?) becoming deprecated, I would not use it. It should be set to false by default, but if you want to be sure you can add SELENIUM_PROMISE_MANAGER = false; to your conf file. The way that protractor has been moving is to use async/await, so your sendKeys function would look like:
let field = element(by.css('CSS.Selector'));
await field.clear();
await field.sendKeys('abc');
Because these are async functions, you will need to define your function properly, so a basic spec would look like:
describe('Demonstrating async/await',function(){
it('Should send some keys', async function(){
let field = element(by.css('CSS.Selector'));
await field.clear();
await field.sendKeys('abc');
});
});
The important difference there is that a function needs to be defined as async function(). As far as reading the code goes, await simply can be read as "Wait until promise resolved to move on". It does get a bit tedious and you feel like you write await before every line of code (you basically do), but I find it significantly better than .then() trees.

What does the exception "ArgumentError: a promise has already been chained" mean, and how do I debug it?

I'm going a little nuts working with Volt at the moment. The moment I try to do something a bit more complicated I end up getting the exception "ArgumentError: a promise has already been chained" in the browser console.
The stack trace doesn't point to anything I can interpret as useful.
That does this error actually mean, and how do I go about trying to track down the cause?
I'd post some code, but some of these errors appear on page load with no indication of where the problem is, so I'd need to post the entire app :/
Volt uses Opal's promise implementation, which I believe is based on the A+ spec in JS land. The error your seeing is because a promise can only have a single .then or .fail block on it. Each .then or .fail will return a new promise that you can then chain off of.
So you can do this:
promise = Promise.new
promise2 = promise.then do
..
end
promise2.then do
..
end
(notice I'm assigning promise2 instead of chaining off of the first one again)
But you can not do something like this:
promise = Promise.new
promise.then do
...
end
promise.then do
..
end
(Notice how I called .then on promise more than once)
A more compact way to write the first is to chain off of the end's
promise = Promise.new
promise.then do
..
end.then do
..
end.fail do
..
end
Volt bindings expect a promise that hasn't been chained on. Also, I think I can make it work where you can chain multiple times, though I haven't thought through all of the implications of this, so I could be wrong. If I get some time I might write a new promise implementation that can handle this. If your still seeing that error and the above doesn't explain why its there, let me know. Thanks!

How to convert a promise in protractor to a string

I am a bit new to Protractor and Jasmine, and I am trying to check if a list of elements that I have fetched using getText() contains a particular element:
Consider the following elements
var productNameElements = element.all(by.css('.table-row')).getText();
elementToBeSearched = element(by.css('.table-row .table-row-child(1)')).getText();
Now since both the variables above would return a promise, therefore by doing:
expect(productNameElements).to.eventually.contain(elementToBeSearched);
would fail, and it does fail.
Therefore, I believe that converting elementToBeSearched into a string would be beneficial and would make my life easier. Please suggest a solution on how can I convert a getText() promise to a string. Thanks
Lets say that the element is ele. So the way you should resolve the promise is-
ele.getText().then(function(str){
expect(someOtherElement.getText()).toBe(str);
})
The .then resolves the promise for you. You can confirm the string by puting a console.log(str)before you compare with expect.
PS: The promise inside the expect parenthesis is automatically resolved.
What i did was mostly similar:
productNameElements = element.all(by.css('.table-row')).getText().then(function(name) {
expect(productNameElements).to.eventually.contain(name);
});
This seems to have done the trick for me as I also checked the value of 'name' using console logging
Below code works for me:
let txt = (await elementToBeSearched.then()).toString();

Resources