Expected to find element: undefined, but never found it - javascript

I'm performing E2E testing and trying to select the two check box from this list.
export class SignupPage {
select_cuisine='.anchor'
selectcuisine(){
cy.get(this.select_cuisine.type="checkbox").check('Coffee & Tea')
}
}
import { SignupPage } from "./Pages/signup_page"
it.only('Sign up', function () {
signupage.selectcuisine()
})
Error message.
I want to select at least two checkboxes from the list to complete my end-to-end testing flow.

I don't think .anchor is a very useful selector, it's used for formatting and may change or appear on multiple elements. Also, that element is just the label for the list. You would want to select the list header using.dropdown-check-list.
export class SignupPage {
select_cuisine='.dropdown-check-list'
selectcuisine(){
cy.get(this.select_cuisine) // dropdown list
.find('li:contains("Coffee & Tea")') // list item required
.find('[type="checkbox"]') // find the checkbox
.check()
}
}

Related

How to update react component props (and rerender) from "outside React"

My application is mixed with vanilla JS and React components, and I have a component that I would like to rerender by changing the props from outside the react component. How would I accomplish this? And maybe I need to be using "state" instead?
This component is only shown when a user clicks a dropdown link in a list of items. Because the list can be quite long, I am trying to be efficient with creating only one component and then changing the props (rerendering) depending on which item in the list if clicked.
This is the code the initially creates the component with references to the "root" and "element"
// Render AdjustDateFormulaComponent
let rootContainer = document.getElementById('rc_dateFormulaComponent');
if (rootContainer) {
this.dataFormulaWidgetRoot = createRoot(rootContainer);
this.dataFormulaWidgetElement = createElement(AdjustDateFormulaComponent, {
id: null,
entityType: 'taskTemplateEntry',
onSave: _this._dateFormulaUpdated, // callback method
});
this.dataFormulaWidgetRoot.render(this.dataFormulaWidgetElement);
}
When item is clicked, rerender by changing props (specifically the "id" field) and show/move in the appropriate dropdown div
_this.$widgetDiv.find('.dueDateAdjustDropdown').on('show.bs.dropdown', function () {
// Change props/rerender here with correct id
this.dataFormulaWidgetElement.props = { id: 124 }; // <--- THIS DOESNT WORK OBVIOUSLY
// When dropdown shown, move react component into dropdown div
$(document.getElementById('rc_dateFormulaComponent'))
.detach()
.appendTo($(this).find('.dropdownContent'));
});
Many thanks in advance.

trying to select checkboxes which have a specific class

Here is my code where i am trying to select the images which only the specific class attached to it
$("#allimages").change(function () {
$('input:checkbox:not("#checkAll")').prop('checked', $(this).prop('checked',$(this).hasClass('isImage')));
});
but it is selecting all checkboxes ignoring if any class is attached to it or not
Without seeing the HTML, it's hard to know what you're trying to accomplish.
I would suggest the following based on what you have provided:
$("#allimages").change(function() {
$("input[type='checkbox'].isImage:not('#checkAll')").prop('checked', $(this).prop("checked"));
});
When #allimages is changed, that same value will be sent to all checkboxes that have class isImage and is not #checkAll.

Using bootstrap-select from elm

A am trying to use bootstrap-select - a javascript/css library extending the html-select-tag with nice features and style. At first glance, calling it from elm seems simple. Indeed, the snipped
view : Model -> Html Msg
view model =
select [ class "selectpicker", attribute "data-live-search" "true" ]
[ option [] [ text "foo" ]
, option [] [ text "bar" ]
]
yields a nice (searchable) select box with two items. However, things get complicated in dynamic situations. Suppose our elm model is a boolean deciding wether the select box is shown or not.
type alias Model = Bool
init : Model
init = True
update : Msg -> Model -> Model
update Toggle model = not model
view : Model -> Html Msg
view model =
if model then
div []
[ select [ class "selectpicker", attribute "data-live-search" "true" ]
[ option [] [ text "foo" ]
, option [] [ text "bar" ]
]
, button [ onClick Toggle ] [ text "toggle" ]
]
else
button [ onClick Toggle ] [ text "toggle" ]
When loading the page, we see again a nice select box which disappears when hitting the toggle button. However, when hitting the toogle button again, the select box will not appear again! The reason is that selectpicker nodes are required to be refreshed if content has changed (including enabling/disabling the node). That is, we have to call
$('.selectpicker').selectpicker('refresh');
from the outside Javascript world after our select box has been added to the DOM again.
I tried to solve that problem using ports, but unfortunately I only got elm to fire an event before rendering, so I additionally had to use setTimeout to wait for completion, which is quite hacky. I suppose there must be a neat solution using a custom element, but again, I was not able to figure out how to call the refresh function at the right moment.
Any help is greatly appreciated!
Finally, I managed to wrap bootstrap-select into a (minimal, nonperfect) custom element which automatically refreshes on updates. Here it is:
import { LitElement, html, customElement, property } from 'lit-element';
import * as $ from 'jquery';
import 'bootstrap';
import 'bootstrap-select';
#customElement('lit-select')
export class LitSelect extends LitElement {
#property({ type : Array }) items = []
updated() {
$(this).find(".selectpicker").selectpicker('refresh');
}
createRenderRoot() {
return this;
}
private renderItem(item: string) {
return html`
<option>
${item}
</option>
`;
}
render() {
return html`
<select class="selectpicker" data-live-search = "true">
${this.items.map(item => this.renderItem(item))}
</select>
`;
}
}
This element can be created from HTML as
<lit-select items='["foo", "bar"]'></lit-select>
or from elm as
node "lit-select" [ attribute "items" "[\"foo\",\"bar\"]" ] []
and it also works in dynamic situations as above.
However, an obvious drawback is that the item list has to be given to a lit-select attribute encoded as a json string. So the markup possibilities are rather limited (for example, the user cannot decide wether to give lit-select a bunch of options or a bunch of option groups).
I would be happy to see better solutions but since this is another topic, I will start a followup question soon.

Programmatically checking checkboxes in VueJS

I've got a VueJS application which filters items based on a number of checkbox items like a category filter for a shop.
When a user clicks a checkbox, we fire off an API request and a list of updated items is returned. The URL is also updated with a query string representing the checkbox that they have selected.
If a user navigates to a query stringed URL we want to have the checkboxes relating to the filters in the query string checked. That way if there is a page refresh, all the same checkboxes are checked.
We've done this so far using an if(window.location.search) and then parsing that query string, adding the parsed query string into an object. Passing that object down into the child component as a prop then setting the model the checkboxes are bound to to the query string object on update.
This works and is fine. The issue is theres stuttering and flashing of the checkboxes. You click the checkbox, it initially unchecks after selecting, the when the API response comes back, it select. Not very good for UX. I'm assuming this is because we're modifying the model the checkboxes are bound to while also trying to update it on checkbox click.
So I'm wondering if there's a better way of doing this please and if someone else has tackled a similar issue.
I've attached some code below, but as its spread across multiple components its quite hard to display here.
Thanks
<template>
<ul>
<li v-for="(filter, index) in filters" v-bind:key="index">
<input type="checkbox" name="filters" v-model="checked" v-on:change="changeItems">{{filter.filterName}}
</li>
{{checked}}
</ul>
</template>
<script>
export default {
data() {
return {
checked: []
}
},
props: [
'filters',
'checkedFilters' //passed object of filters in query string
],
updated: function() {
this.checked = this.checkedFilters
},
methods: {
changeItems: function (){
this.$emit('change-items', this.checked)
}
}
}
</script>

Javascript style changes break Selenium(GEB) test

I am currently working on a pretty simple input form with various input elements, such as selects, texts and radiobuttons. The form is validated upon post and if not validated successfully the form is displayed again with erroneous fields highlighted. The highlight is achieved by adding a class has-error and appending a div with an error message. Upon correcting the error - say checking one of the radio-buttons in a group - the onChange event is captured and it removes the has-error class and the div:
if ($(obj).parents('div.has-error')) {
$(obj).parents('div.has-error').removeClass('has-error');
$(obj).parents('div.has-error').find('div.help-block').remove();
}
It works exactly as intended when performed by a "real" user. However when the exact same thing is performed by a Selenium (GEB) test, the radiobutton isn't checked. For a short while it has the "focus" dotted line as if it tabbed through the element.
Hence the test fails since the radiobutton is never checked. If I remove the above mentioned javascript it works just fine... And likewise if I remove just one of the two statements....
The test is written with GEB and uses "form-control-shortcuts" to set the value of the fields by name, like:
class FormModule extends Module {
static base = { $('form#personform') }
static content = {
personskoen { "person.koen"().module(RadioButtons) }
}
}
class OpretPersonPage extends Page {
static url = "person/opret"
static at = { title.contains("person.opret.titel") }
static content = {
form { module FormModule }
}
}
And the value is set in the test like this:
def () {
given:
at OpretPersonPage
when:
page.form.persoenskoen = "KVINDE"
then:
page.form.persoenskoen == "KVINDE"
}
I am completely stuck and have no further ideas to test. I really hope you guys have some!
I am using:
org.seleniumhq.selenium:selenium-firefox-driver:2.52.0
org.seleniumhq.selenium:selenium-support:2.52.0
org.seleniumhq.selenium:selenium-server:2.52.0

Categories