Cypress: Check list of hrefs, assert they do NOT contain a certain string - iteration

I have a list of hrefs that I need to check. I only need to make sure that none of them contains the string "creditcheck"
The html looks like this:
<div class="yiiTab clearfix content-right-side" id="clientinfotabs">
<ul class="tabs left-side-tabs">
<li>
<a reloadonclick="" loadurl="/index.php?r=foo/bar;id=12345&language=de" href="#foofoobar" class="active">Test<span class="tab-item-count">8</span></a></li>
<li>
<li>
<li>
<li>
.
.
.
</ul>
The general idea was this:
Get ul
Iterate through every li item
Get 'a' using .children()
Invoke href and compare to a string
I tried to iterate through the list and check the hrefs using several approaches. This is my latest attempt:
describe('check hrefs', () => {
it('check hrefs', () => {
cy.login()
cy.visit('url3')
cy.get('tbody > :nth-child(1) > .col-id-large').click({force: true})
cy.get('#clientinfotabs > ul')
.each(($el) => {
cy.get($el).children().invoke('attr','href').should('not.include','creditcheck');
})
})
})
That's what Cypress returns when I run this script:
AssertionError
Timed out retrying after 10000ms: object tested must be an array, a map, an object, a set, a string, or a weakset, but undefined given
cypress/integration/test2.spec.js:10:62
8 | cy.get('#clientinfotabs > ul')
9 | .each(($el) => {
> 10 | cy.get($el).children().invoke('attr','href').should('not.include','creditcheck');
| ^
11 | })
12 | })
13 | })

So you are really close. Instead of cy.get() you have to use cy.wrap(). And also you can directly loop over li using the selector #clientinfotabs > ul > li.
describe('check hrefs', () => {
it('check hrefs', () => {
cy.login()
cy.visit('url3')
cy.get('tbody > :nth-child(1) > .col-id-large').click({force: true})
cy.get('#clientinfotabs > ul >li').each(($el) => {
cy.wrap($el).invoke('attr', 'href').should('not.include', 'creditcheck')
})
})
})

Related

Correct way to implement drill-down tags in vue with vuetify

I am using a v-chip-group with v-chips to represent a tag cloud for records in my database. I have an object array with records that look something like { key:'device', count:100}. A record could have multiple tags, so as you click on a tag, a new query is made that filters on that tag, the result will then have a new tag cloud with a subset of the previous.
It looks something like this:
tag1 (1000), tag2 (100), tag3 (100)
When you click on tag1 you end up with:
tag1 (1000), tag3 (15) (no tag2 because there is no overlap between tag1 and tag2).
Here is the relevant template code:
<v-chip-group v-model="selectedTag" multiple #change="refresh">
<v-chip v-for="tag in tags" :key="tag.key" active-class="primary">
<v-avatar left class="grey">{{ tag.count }}</v-avatar>
{{ tag.key }}
</v-chip>
</v-chip-group>
The problem I have is that in the typescript I do something like this:
refresh() {
// get simple array of tag strings
const selectedTags = this.selectedTag.map((value: any) => {
if (this.tags && this.tags[value]) {
return this.tags[value].key
} else {
return null
}
}).filter((value: any) => {
return value != null
})
Promise.all([
...
ApiCall('GET', 'tags', {limit: 1000, tags: selectedTags}),
...
).then((values) => {
// decode response from server into new tags
this.tags = values[2].series['0'].values.map((item: any) => {
return {key: item.bucket, count: item.doc_count}
})
const newTags: number[] = []
this.tags.forEach((tag, index) => {
// find the new index of the previously selected tags and save them
if (selectedTags.find(st => {
return st === tag.key
})) {
newTags.push(index)
}
})
// update selectedTag with the new value
this.$set(this, 'selectedTag', newTags)
// did not work this.selectedTag = newTags
})
}
What I'm seeing is that when I click a chip, it correctly fires the #change event and calls refresh, but then when the refresh finishes, I see an additional refresh get called with an empty selectedTag, which clears my filters and recalls the above functionality.
Is there a way to get #change to fire when a chip is changed, but not fire (or filter it out) when the event is generated by changing the data referenced by v-model?

filter an object key:val in vue

I have an object with key:val I want to filter the object by value like "ג6"
how i do that? I dont have alias name for search
this is the object
specialityTest={
"4969": "ג6",
"4973": "ג19",
"5163": "ה",
"5165": "ה1",
"5200": "ה2",
"5486": "גן1"
}
I want to do
this.nurseListSpeciality2 = this.specialityTest.filter((el) => {
return el.value == "fffff";
});
I get an error:
this.specialityTest.filter is not a function
how can I filter this object?
You can use Object.keys for filtering your keys where the values match.
this.nurseListSpeciality2 = Object.keys(this.specialityTest).filter((val) => this.specialityTest[val] === "ג6");
Finally, when rendering you can loop over the array of keys that will be returned and the render values associated with those keys
<ul>
<li v-for="val in nurseListSpeciality2" :key="val">
{{ specialityTest[val] }}
</li>
</ul>

Vue v-for changing from version 1 to version 2

I'm learning Vue.js and found this fiddle that does exactly what I want to do.
Here is the fiddle: https://jsfiddle.net/os7hp1cy/48/
I integrated this and am getting this error:
invalid expression: v-for="user in users | filterBy searchKey | paginate"
So I've done some digging and I see it has changed from version 1 to 2. However, I don't know how to fix this.
<li v-for="user in users | filterBy searchKey | paginate">{{ user.name }}</li>
I would like to replace this with something that Vue 2 will support and will work the same way.
As of Vue version 2, filters can only be used inside text interpolations ({{ }} tags). See the documentation for migrating from Vue version 1.
You can use a computed property to filter the users and use that computed property in the v-for directive instead:
computed: {
filteredUsers: function() {
let key = this.searchKey.toUpperCase();
return this.users.filter((user) => {
return user.name.toUpperCase().indexOf(key) !== -1
})
},
paginatedUsers: function() {
var list = this.filteredUsers;
this.resultCount = list.length
if (this.currentPage >= this.totalPages) {
this.currentPage = this.totalPages
}
var index = this.currentPage * this.itemsPerPage
return list.slice(index - 1, index - 1 + this.itemsPerPage)
}
}
<li v-for="user in paginatedUsers">{{ user.name }}</li>
Also, when using v-for to generate a range of numbers like you do for your page numbers, Vue version to starts the index at 1 instead of 0. So, you'll need to update the logic depending on a starting index of 0 as well.
Here's a working fiddle.

Vue.js When applying multiple filters a list, how can you display a count/total of the results

lets say I have a large object of people. and I want to filter them by hair color and gender. Once the filtering has taken place - how can i display the total number of results?
here is some pseudo code to help explain:
Vue.filter('hairFilter', function(person, color){
return person.filter(function( item ){
return item.hair == color
})
});
Vue.filter('genderFilter', function(person, gender){
return person.filter(function( item ){
return item.gender == gender
})
});
<h1>Total Results: [TOTAL FILTERED RESULTS NUMBER HERE]</h1>
<ul>
<li v-for="person in people | hairFilter 'red'| genderFilter 'male'">{{person.name}}</li>
</ul>
Thanks in advance
You can use a computed property and $eval.
{
computed: {
filteredPeople: function () {
return this.$eval("person in people | hairFilter 'red'| genderFilter 'male'");
}
}
}
Then in your template do like:
<h1>Results {{ filteredPeople.length }}</h1>
<ul>
<li v-for="person in filteredPeople">{{ person.name }}</li>
</ul>

Undefined variable: lang laravel

I got a problem the file cannot find the variable 'lang'.
{{ Form::open(['action' => 'loon.language']) }}
{{Form::select('lang',['nl'=>'nl','po'=>'po'], $lang,['onchange'=>'submit()'])}}
{{$lang = 'blaat'}}
{{var_dump($lang)}}
{{ Form::close()}}
Controller:
public function postChangeLanguage()
{
$rules = [
'language' => 'in:nl,po' //list of supported languages of your application.
];
$language = Input::get('lang'); //lang is name of form select field.
$validator = Validator::make(compact($language),$rules);
// $language = Session::get('language',Config::get('app.locale'));
if($validator->passes())
{
Session::put('language',$language);
App::setLocale($language);
}
else
{ /**/ }
}
Route:
Route::get('language', array(
'uses' =>'LoonController#postChangeLanguage',
'as' => 'loon.language'
));
Filter.php:
App::before(function($request)
{
$language = Session::get('language','nl'); //en will be the default language.
App::setLocale($language);
});
Ill even tried to debug it and still this error code!
Undefined variable: lang (View: /Users/nielsvandijk/loon/rekentool/app/views/partials/header.blade.php) (View: /Users/nielsvandijk/loon/rekentool/app/views/partials/header.blade.php)
Can someone help?
The first time you are using $lang it is still empty apparently..
A quick fix would be to use an # sing in front of it (allowing it to be undefined)
{{Form::select('lang',['nl'=>'nl','po'=>'po'], #$lang,['onchange'=>'submit()'])}}
The purpose of the lang variable is to define the "selected" element in the select field
{{Form::select('lang',['nl'=>'nl','po'=>'po'], 'po',['onchange'=>'submit()'])}}
This would result in:
<select name="lang">
<option value="nl">nl</option>
<option value="po" selected="selected">po</option>
</select>
In the controller you could set the default language if no language is preselected
View::make('view')->with('lang','nl');