Cypress: Is it possible to select an item out of a dynamic dropdown with only a partial word/s? - drop-down-menu

I have a dropdown list which is always increasing in the number of options available. I Have the 'RecieptName' from the option, however, it is followed by text that is constantly changing. eg: RecieptName: 'Changing sentence including words and numbers'.
What I am trying to do is something along the lines of:
cy.get('#RecieptName').select('RecieptName:');
However, it can't find an option with it as it is followed by changing the numbers. Is it possible to find the option based on a partial option?

You would need to scan the options first, find it's index and select by number
Using .contains() command
cy.get('option')
.contains('ReceiptName:')
.invoke('index') // index among siblings
.then(index => {
cy.get('dropdown').select(index);
})
Using a regex
cy.get('option')
.contains(/^ReceiptName:/)
.invoke('index') // index among siblings
.then(index => {
cy.get('dropdown').select(index);
})
Using selected prop
cy.get('#RecieptName option')
.contains(/^ReceiptName:/)
.invoke('prop', 'selected', true)

The option containing the the text "RecieptName:" can be selected by adding :contains()
cy.get('#RecieptName option:contains(RecieptName:)')
.then($option => {
cy.get('#RecieptName').select($option.text())
})
cy.get('#RecieptName option:contains(RecieptName:)')
.then($option => {
cy.get('#RecieptName').select($option.index())
})

filter will get the DOM element that match a specific selector. Once we get the element, then we get the exact text of RecieptName option by using the invoke(text) and then we pass the same text to the select command, something like this:
cy.get('#RecieptName option')
.filter(':contains("RecieptName:")')
.invoke('text')
.then((recieptNameText) => {
cy.get('dropdown').select(recieptNameText)
})
You can also use the value attribute to directly select the dropdown as I can see the value attributes are unique, I guess that would be the cleanest way to do this:
cy.get('select#RecieptName').select('scoredesc')
cy.get('select#RecieptName').select('modifieddesc')
cy.get('select#RecieptName').select('createdasc')

Related

Cypress - verify if each table row in one column contains the same item and ignoring header

I have a filtered table, a grid table created by DIVs, so no real table elements, that I want to confirm that my filter has worked in but the ways I have tried keep trying to also check the header which is then telling me that my results are wrong
cy.get('div[data-field="name"]')
.then($col => {
const count = $col.length
.wrap($col)
.should('have.text', 'Bob'.repeat(count))
})
I have 3 bobs in my example, but it is also viewing the header so I am getting an error telling me that it is trying to find 3 instances of Bob but also finds Name, so finds 4.
If I try
cy.get('div[data-field="name"]')
.each($col => {
expect($col.text()).to.eq('Bob')
})
It fails as it tells me the first entry is 'Name' as it is finding the header and I am not sure how to avoid it counting/reading the header.
I'm sure its something simple that I am missing and not thinking of but any help is appreciated!
NOTE: I got both these ways of checking from this other stack answer Cypress - verify if each table row in one column contains the same item
There are probably many ways to solve this, here are a couple.
For the first sample, take one off the count (since there is only one header)
cy.get('div[data-field="name"]')
.then($col => {
const count = $col.length
.wrap($col)
.should('have.text', 'Bob'.repeat(count-1))
})
For the second sample, don't look at the first element
cy.get('div[data-field="name"]')
.each(($col, index) => {
if (index > 0) {
expect($col.text()).to.eq('Bob')
}
})

How can I get my cypress custom command to ingest this data (i think i structured the data wrong)?

Alright, as the title says- i'm trying to write a custom command for a cypress test suite. The situation as as follows: I have several tests that need to select an indeterminate number of fields and select an option from the each fields list of drop downs.
The logic for this is crayons-in-mouth simple and works fine:
cy.get(selector)
.select(selection)
.scrollIntoView()
and this works great. But because I use it a lot it's a lot of highly repetitive code so I'm trying to create a custom command where I can just inject an array of arrays (various sets of selectors and selections depending on the situation) into it and it'll do the rest.
This is the custom command as I have it written now.
commands.js
Cypress.Commands.add("assignImportFields", (array) => {
cy.wrap(array).each((selector, selection) => {
cy.get(selector)
.select(selection)
.scrollIntoView()
cy.log('using ' + selector + ' to select ' + selection)
})
})
I have the data in a seperate file that looks like this:
data.js
const importFields = {
actorListImports : [
[selectors.lastName, 'Last_Name'],
[selectors.firstName, 'First_Name'],
[selectors.phoneNum, 'Phone_Number']
]
}
exports.importFields = importFields;
and finally, in my test file:
tests.js
const {actorListImports} = data.importFields;
cy.assignImportFields(actorListImports)
The response I get from this is that the 'select' failed because it requires a dom element. My selectors are fine, so I think it's trying to use an entire array (both selector and selection at once) as the selector instead of the first part of the array.
I know i'm not structuring the data correctly, but i've tried a few different variations of it and my primitive monkey brain just can't put together.
Can someone help me identify what's wrong with how i've structure this?
You need to de-structure the array elements in the .each() parameter list, like this cy.wrap(data).each(([selector, selection])
This is a minimal example:
const selectors = {
'lastName': 'lastName'
}
const data = [
[selectors.lastName, 'Last_Name'],
// [selectors.firstName, 'First_Name'],
// [selectors.phoneNum, 'Phone_Number']
]
cy.wrap(data).each(([selector, selection]) => {
console.log(selector, selection)
expect(selector).to.eq('lastName') // passing
expect(selection).to.eq('Last_Name') // passing
})

rethinkdb - hasFields to find all documents with multiple multiple missing conditions

I found an answer for finding all documents in a table with missing fields in this SO thread RethinkDB - Find documents with missing field, however I want to filter according to a missing field AND a certain value in a different field.
I want to return all documents that are missing field email and whose isCurrent: value is 1. So, I want to return all current clients who are missing the email field, so that I can add the field.
The documentation on rethink's site does not cover this case.
Here's my best attempt:
r.db('client').table('basic_info').filter(function (row) {
return row.hasFields({email: true }).not(),
/*no idea how to add another criteria here (such as .filter({isCurrent:1})*/
}).filter
Actually, you can do it in one filter. And, also, it will be faster than your current solution:
r.db('client').table('basic_info').filter(function (row) {
return row.hasFields({email: true }).not()
.and(row.hasFields({isCurrent: true }))
.and(row("isCurrent").eq(1));
})
or:
r.db('client').table('basic_info').filter(function (row) {
return row.hasFields({email: true }).not()
.and(row("isCurrent").default(0).eq(1));
})
I just realized I can chain multiple .filter commands.
Here's what worked for me:
r.db('client').table('basic_info').filter(function (row) {
return row.hasFields({email: true }).not()
}).filter({isCurrent: 1}).;
My next quest: put all of these into an array and then feed the email addresses in batch

Removing a field and updating another field in a document

Is it possible to remove a field from a document and update another field in the same document in one query?
Afaik, to remove field, you have to use a replace query, like so:
r.db("db").table("table").get("some-id").replace(r.row.without("field-to-remove"))
And to update:
r.db("db").table("table").get("some-id").update({ "field-to-update": "new-value" })
But chaining these two together doesn't work. I get a "RqlRuntimeError: Expected type SELECTION but found DATUM" error when running the following query (the order of the replace/update doesn't matter):
r.db("db").table("table").get("some-id").replace(r.row.without("field-to-remove")).update({ "field-to-update": "new-value" })
Try:
r.db('db').table('table').get('id').update({
"field-to-remove": r.literal(),
"field-to-update": "new-value"
})
You don't need to use replace here since you don't care about explicitly setting the other fields.
You can use replace with without and merge inside of your replace function:
r.table('30514947').get("492a41d2-d7dc-4440-8394-3633ae8ac337")
.replace(function (row) {
return row
.without("remove_field")
.merge({
"field-to-update": "hello"
})
})

WatiN SelectList - How can I select any element from the list?

I'm using WatiN to do some web testing and have run into a problem with a select list.
I have to run through a few pages first, adding a 'Category' element that will populate said troublesome select list.
I have been able to easily select an element from the list using ByValue, but the problem here is that the values is more of an index element that is created on the fly with a seemingly random value when the 'Category' element is created. I have tried to use the text that is under the option list in the html but it cannot seem to find it.
At this point I'm willing to settle for any element in the list that isn't value "-1" as this is the "Please select an option item".
Any help at all would be appreciated,
Thanks in advance
Keith 8o8
If i understand correctly maybe this can help:
OptionCollection options = browser.SelectList("elementId").Options;
options[0].Select();
Here is a solution :
SelectList list = _browser.Frame(Find.ById(frameId)).SelectList(listId);
foreach (Option tempOption in list.Options)
{
string value = tempOption.Text;
if (!string.IsNullOrEmpty(value)) // Compare with visible option text
{
if (value.Equals(option))
{
list.Option(option).Select();
found = true;

Resources