How to get count of urls present in sitemap.xml file - cypress

Can anyone help me to know how we can take count of urls present in sitemap.
Thanks in advance

Use jQuery to count the urls
cy.request('sitemap.xml')
.its('body')
.then(xml => {
const count = Cypress.$(xml).find('url').length;
cy.log(count)
})

Assuming all your url’s have a tags, and you have to assert the count you can do like this:
cy.get('a').should('have.length', 10)
If you just want to print the length you can like this:
cy.get('a')
.its('length')
.then((len) => {
cy.log(len) //prints length
})

Related

Cypress number of elements in a table

Is there an easier way to count the number of elements in a table via Cypress?
I have a 3 column table and I want to count, how many times is "India" in my table.
I tried it this way:
cy.get('ag-grid-table').contains(country).its('length').as("countrylength");
cy.get('#countrylength').then((ccc) => {
cy.log(ccc)
})
but this gives me always 1, as it finds only first element.
Then I have this solution, that may probably work:
let count = 0;
cy.get('ag-grid-table div.ag-row').each(($el, index, $list) => {
if($el.text().includes(country))
{ count ++; }
}
but can't we just find that country with one line command using length()?
You could just move the contains() inside the selector, it gets around the restriction of only returning the first result.
You need to merge the country variable into the selector as well, either with a string template as below, or by concatenating strings (+ operator).
cy.get(`ag-grid-table div.ag-row:contains("${country}")`)
.its('length').as("countrylength");
cy.get('#countrylength').should('eq', 3)
You can use the filter command for this:
cy.get('ag-grid-table div.ag-row')
.filter(':contains("India")')
.should('have.length', 3)
In case you want to use the length of different tests in your project you can use Cypress.env(). As aliases as are removed after every test.
cy.get('ag-grid-table div.ag-row')
.filter(':contains("India")')
.its('length')
.then((len) => {
Cypress.env('length', len)
})
//To use it in other test
cy.get('selector').type(Cypress.env('length'))
cy.get('selector').should('have.length', Cypress.env('length'))
If you want to use the alias value later in the test, or in another test you could access it directly from the "Mocha context" by using a function callback
if('tests the ag-grid', function() { // now alias value is available on "this"
cy.get('ag-grid-table div.ag-row')
.invoke('text')
.then(text => text.match(/India/g).length) // number of occurrences in table
.as("countrylength");
cy.get('.flags').should('have.length', this.countrylength)
})

Horizon/RethinkDB api

So I have one error and two questions about Horizon. (http://horizon.io/docs/)
I have a simple table and 1 record inside, this is the row:
id: "o34242-43251-462...",
user_id: "3lw5-6232s2...",
other_id: "531h51-51351..."
When I run hz serve I'm getting this error:
Unexpected index name (invalid field): "hz_[["user_id"],[["other_id","0"]]]".
Okay, okay, invalid field... But I didn't find any informations about "valid" fields. Anybody knows the answer? What can I do?
My questions:
How to run Horizon "forever" on ubuntu? Now I'm using just hz serve and "&",
If I have few queries, for example:
let table = this.horizon('firstTable');
let table2 = this.horizon('secondTable');
table.find(someId).fetch().subscribe((item) => {
//and then I want to run other query, e.g:
table2.find(item.id).fetch().subscribe((value) => {
//and here again run other query... <-- how to avoid this?
});
});
How to e.g return a value from horizon's query, and then use this value inside other query? I don't want to write it all in one function...
Thanks for any help.
Since 'fetch' returns an RxJS observable, and it yield one result only, you can use 'toPromise' to consume it in a convenient fashion.
let table = this.horizon('firstTable');
let table2 = this.horizon('secondTable');
let item1 = await table.find(someId).fetch().toPromise();
let item2 = await table2.find(item1.id).fetch().toPromise();
Or without ES7 await, just using Promise.then:
table.find(someId).fetch().toPromise().then((item1) => {
table2.find(item1.id).fetch().toPromise().then((item2) => {
// take over the world from here
});
});

RxJs Observable: Execute function if empty/filtered

I've got an Observable that listens to some user input from a text box. If the observed string's length is >=3 (filter), it executes some HTTP call (switchMap).
Now I'd like to detect somehow if the user input has been filtered. Reason:
If the HTTP call has been done, it should show the results.
If the user input got filtered (== is invalid), it should clear the results.
Here's the code I'd like to have (see: ifFiltered):
this.userInput.valueChanges
.filter(val => val && val.length >= 3)
.ifFiltered(() => this.results = [])
.switchMap(val => getDataViaHTTP())
.subscribe(val => this.results = val);
I know, I could place that logic within the filter function for this simple example. But what if I have 10 different filters?
Did I miss any method that satisfies my needs?
Thanks in advance!
Either use partition like here RxJS modeling if else control structures with Observables operators
Or instead of filter use map and pipe the object if the former filter condition is true or null otherwise. so you can catch the null where ever you want in your chain with a filter.
Last option call some function in the else part of the filter function
We've had a similar case and tried it with partition as mentioned above but found it much handier to use throw here. So for your code
this.userInput.valueChanges
.do(val => {
if (!val || val.length < 3) {
throw new ValueTooShortError();
}
})
.switchMap(val => getDataViaHTTP())
.do(val => this.results = val)
.catch(() => this.results = [])
.subscribe();
I suggest having a common event stream, creating two filtered streams, and merging the two before subscription:
var o = this.userInput.valueChanges;
var empty= o.filter(t=> t.length < 3)
.map(t=>[])
var nonempty = o.filter(t=> t.length >= 3)
.switchMap(t=> getDataViaHTTP());
empty.merge(nonempty).subscribe(val => this.results = val);
I found another nice solution for my use case using Validators:
(I know that this is no solution using Observables as the question stated. Instead it's using Angular2 features to workaround the problem nicely.)
this.userInput.validator = Validators.compose([
Validators.required,
Validators.minLength(3)
]);
this.userInput.valueChanges
.filter(val => this.userInput.valid)
.switchMap(val => getDataViaHTTP())
.subscribe(val => this.results = val);
Now I can use the userInput.valid property and/or the userInput.statusChanges Observable to keep track of the input value.
May be it's late, but wanted to post for the members still seeking a more cleaner approach to validate IF EMPTY inside .map:
of(fooBar).pipe(
map(
(val) =>
({
...val,
Foo: (val.Bar
? val.Foo.map((e) => ({
title: e.Title,
link: e.Link,
}))
: []) as fooModal[],
}));
This code returns a empty array if val.bar is missing, but it's just an example you can use any validation & expression instead.

Equivalent of Right() function

Is there an equivalent of right() function that I can use in jquery. I want to get records with fileextension xlsx.
new Guid(context.Documents.Where(T => T.FileName == ".xlsx").Select(T => T.ItemGuid).First().ToString());
something like
select * from document where right(filename,4) = 'xlsx'
I don't want to store the filename in a variable and later manipulate it. I want to be able to directly use it in my where condition. 'Documents' is my table name and "FileName" is a field that holds names of the file that I upload, now I need to get filter only the files that has the extension 'xlsx'. I tried doing
guid temp = new Guid(context.Documents.Where(T => T.FileName.Substring(T.FileName.Length - 4) == ".xlsm").Select(T => T.ItemGuid).First().ToString());
but I get the error "Sequence contains no elements" error.
* Update: Used the EndsWith() to get the information I wanted. This works now:
guid temp = new Guid(context.Documents.Where(T => T.FileName.EndsWith("xlsm")).Select(T => T.ItemGuid).First().ToString());
thanks.
filename.substr(-4)
Using .substr with a negative index will return a substring from the end of the string.
You can use .slice (MDN) function, taking into account that passing a negative value into it makes it cut the string from the end. )
var test = 'filename.xslx';
if (test.slice(-4) === 'xslx') {
alert("Passed");
}
right() is the same as endswith()
function endsWith(str, suffix) {
return str.indexOf(suffix, str.length - suffix.length) !== -1;
}
You might be looking for [name$="value"] selector documented here.
There is not, you can use
var filename = "file.xlsx";
var extension = filename.substr(filename.length - 4);
or to get the characters after the dot, you could use:
var extension = filename.split('.').pop();
Use could javascript match() which provides regex matching.
var filename = 'somefile.xlsx';
var matches = filename.match('/\.xlsx$/i');
if (matches.length > 0) {
// you have a match
}

Filtering a List with another List Inclusive

i have a list of filter names: FILTERBYNAMES
my query result items each contain a name list: NAMES
I want to filter the result an take all items whose name list contains at least one name in the FILTERNAMELIST:
results= result.where(r=>r.NAMES.CONTAINS(...?)...?
I think you need something like:
var results = list.Where(i => i.Names
.Any(name => filterNameList.Contains(name)));
You can solve this by looking at the intersection of the two name sets.
var filteredResult = result.Where(i => i.Names.Intersect(filter).Any());
To limit the enumerations of the filter, you could use a hashset...
HashSet<string> hashedFilter = new HashSet<string>(filterByNames);
var results = result
.Where(x => x.Names
.Any(name => hashedFilter.Contains(name))
);

Resources