Testing vuetify v-select with laravel dusk - laravel-5

Does anyone know how to test vuetify v-select with laravel dusk?
I've tried $browser->select('size', 'Large'); without success
this is one of the v-selects that i want to test
<v-flex class="form__item">
<v-select
id="estatus"
dusk="estatus"
v-model="form.id_estatus"
label="Estatus"
:items="estatus"
item-text="nombre"
item-value="id"
v-validate="{ required:true }"
data-vv-name="estatus"
data-vv-as="estatus"
:error-messages="(errors.collect('estatus'))"
required
></v-select>
</v-flex>
And this the generated HTML
When v-select is clicked, shows the option list in other part of the HTML

Click on the .v-select element and wait for the select to open up:
$browser->click('.v-select');
$browser->waitFor('.v-menu__content');
Then you can select an option by index:
$browser->elements('.v-menu__content a')[2]->click();
Or by text (using XPath):
$selector = "//div[#class='v-menu__content menuable__content__active']//div[text()='State 3']";
$browser->driver->findElement(WebDriverBy::xpath($selector))->click();

(1) In the Vue template:
Wrap the <v-select> with a <div id="selectStatus"></div>
(2) In the Dusk test, use:
$browser->click('#selectStatus .v-select');
$browser->waitFor('.menuable__content__active');
$browser->elements('.menuable__content__active a')[1]->click();
$browser->waitUntilMissing('.menuable__content__active');
$browser->assertSeeIn('#selectStatus .v-select','theStatusIExpectToSee');
— OR —
The <v-select> can be tested without wrapping it in a <div id="foo"></div> if we use a slightly more complicated strategy.
Instead of putting the id on a div wrapper, we can put the id directly on the v-select or even rely on text content contained within the v-select with the following strategy (involving xpath):
use Facebook\WebDriver\WebDriverBy;
public function keyOfParentContainingItem($elements, $itemName, $itemValue = null){
$elWithItemKey = null;
$itemNamePrefix = ($itemName !== 'text()') ? '#' : '';
$itemValueMatchString = ($itemValue !== null) ? '="'.$itemValue.'"' : '';
foreach($elements as $k=>$v){
$xpath = './/*['.$itemNamePrefix.$itemName.$itemValueMatchString.']';
if(!empty($v->findElements(WebDriverBy::xpath($xpath)))){
$elWithItemKey = $k;
}
}
return $elWithItemKey;
}
public function testMyVSelect(){
$this->browse(function (Browser $browser) {
$browser->visit('/myAddress');
$els = $browser->elements('.v-select');
$els[$this->keyOfParentContainingItem($els,'id','idOnVSelect')]->click();
$browser->waitFor('.menuable__content__active');
$menuEls = $browser->elements('.menuable__content__active a');
$menuEls[$this->keyOfParentContainingItem($menuEls,'text()',"some text")]->click();
$browser->waitUntilMissing('.menuable__content__active');
$els = $browser->elements('.v-select');
$key = $this->keyOfParentContainingItem($els,'text()',"some text");
$this->assertTrue($key !== null);
});
}
Using Vuetify 1.5.14.

Click on the v-select element for it to list the options, then wait for the dropdown-menu class to be present before selecting an element from the list (2 in the example below) by clicking on the third tag in the menu list.
Finally, wait until the dropdown-menu class disappears before moving onto the next part of the test.
$browser->click('#region')
->with('#region', function ($vSelect) {
$vSelect->waitFor('.dropdown-menu')
->elements('.dropdown-menu a')[2]->click();
})
->waitUntilMissing('.dropdown-menu');

Related

Laravel dusk scroll and waitFor dynamic element

I have lists which dynamically shows when scroll down the page, for example, when I open the page, there is only <div id="list-0" date="2018-01-01"></div>, and after I scroll down, <div id="list-1" date="2018-01-02"></div> will dynamically shows up, same as <div id="list-2" date="2018-01-03"></div> and <div id="list-3" date="2018-01-04"></div> and so on.
Those lists are not able to see on chrome view-source(ctrl+U)
I want to use laravel dusk to scroll down page if there is no list-n, and retrieve the date attribute.
Here is my code
/** #test */
public function scroll_down_each_list_and_match_the_date()
{
$this->browse(function (Browser $browser) {
$browser->visit('/lists');
$listsLength = $this->listsLength();
for($i = 0; $i <= $listsLength; $i++){
$selector = "div[id=\"list-$i\"]";
while(!$browser->waitFor($selector)){
$browser->driver->executeScript('window.scrollTo(0, 500);');
}
$date = $browser->attribute($selector, 'date');
$browser->assertEquals($date, $this->date($i));
}
});
}
The Assertion Error is
Facebook\WebDriver\Exception\TimeOutException: Waited 5 seconds for selector [div[id="list-1"]].
if I replace while(!$browser->waitFor($selector)) to while(!$browser->element($selector)), it seems like laravel dusk will execute forever and won't stop.
Instead of:
$selector = "div[id=\"list-$i\"]";
Maybe try:
$selector = $browser->attribute('list-$i', 'id');

CKEditor Inlineditor - Select by class instead of ID

So I have a page with several textareas for a custom form I made. I am able to target an individual textarea by it's ID but I would like to know if theres an easy way to have the CKeditor inline target all textareas elements or have editor select elements by their class instead. At the moment I have setup ID for each other but they are each unique, trying to figure out the best aproach but im not good with javascript and would like some assistance with this.
Current code:
<script>
CKEDITOR.inline( 'ID');
</script>
Looking for a code that would target all text areas or at lease target class instead of IDs.
Use CKEDITOR.document.find:
var elements = CKEDITOR.document.find( '.foo' ),
i = 0,
element;
while ( ( element = elements.getItem( i++ ) ) ) {
CKEDITOR.inline( element );
}
You can also use the official jQuery adapter:
$( '.foo' ).ckeditor( function() {
// Callback function code.
}, {
// Config options here
} );
You can use this:
$(".ckeditor").each(function () {
CKEDITOR.replace( $(this).attr("name") );
});
This sample shows how to automatically replace all <textarea> elements of a given class with a CKEditor instance.
To replace a <textarea> element, simply assign it the ckeditor class, as in the code below:
<script src="https://cdn.ckeditor.com/4.11.4/standard/ckeditor.js"></script>
<textarea class="ckeditor" name="editor1"></textarea>
<textarea class="ckeditor" name="editor2"></textarea>
<textarea class="" name="editor3"></textarea>
Note that other attributes (like id or name) need to be adjusted to your document.
ckeditor replacebyclass

Toggle Class Prototype Function

I'm trying to iterate over an array of elements, specified by class name. Then I want to use a function to toggle the class and change some text.
This does NOT work:
$$('.btn').forEach( setButtonLoadingStateOn, this );
setButtonLoadingStateOn = function( btn ) {
btn.toggleClassName('loading');
btn.disable();
btn.select('span span')[0].update( "please wait..." );
}
This does NOT work:
$$('.btn').each( function(btn) {
btn.addClassName('loading');
btn.disable();
btn.select('span span')[0].innerHTML = "please wait...";
});
This also does NOT work:
setButtonLoadingState( '.btn', 'start' );
setButtonLoadingState = function( btnClass, loadState ) {
btnElem = $$( btnClass );
btnElem.each(function( el ){
if ( loadState == 'start' ) {
el.addClassName( 'loading' );
el.disable();
el.select('span span')[0].innerHTML = "please wait...";
} else {
el.removeClassName( 'loading' );
el.enable();
el.select('span span')[0].innerHTML = "buy now";
}
});
}
If I console.log() the element, I get the object (or array) I'm expecting, so I don't know what's wrong.
I've also tried several SO answers, including this one: Add or remove class with prototype
In case it matters, the platform is Magento CE 1.8.0.2. How can I update these button elements using Prototype? Thanks.
~ edit ~
There are several HTML elements on the page. They all look like this:
<button type="button" title="buy now" class="button btn" onclick="productAddToCart(this)">
<span><span>Quick Buy</span></span>
</button>
Thanks so much to all who contributed. The AJAX request was returning a hyphenated key in the JSON response:
{"msg-html":"blah blah blah"}
Reading this from the response object as follows was the problem:
var ajaxResult = transport.responseText.evalJSON();
var ajaxMsg = ajaxResult.msg-html;
Hyphens are not allowed in JSON keys, instead the object needs to be accessed as follows:
var ajaxMsg = ajaxResult["msg-html"];
... or remove the hyphens! Thanks again to all.
Full credit to this dude/dudette: http://developer.appcelerator.com/question/120227/parsing-json-with-hyphenated-key-names

How to use the template function in the grid using kendoui

I am using a template to display some button. I have written the following code :
template: kendo.template($("#edit-template").html())
And in the edit template I have written :
<script id="edit-template" type="text/x-kendo-template">
<a class="k-grid-edit" style="visibility:hidden;" id="edit">Edit</a>
</script>
Initially it will be hidden mode. On databound function, I will show or hide the button. If the permission is shown then I write
$(".k-grid-edit").show();
Whenever I am updating the grid then the edit button is disappearing again. This is because the button is in hidden state initially. After updating also I need to display that in visible mode. How can i do that.
Regards
What about transforming your template into:
<script id="edit-template" type="text/x-kendo-template">
# if (isVisible) { #
<a class="k-grid-edit">Edit</a>
# } else {#
<a class="k-grid-edit" style="display:none">Edit</a>
# } #
</script>
and then have a variable:
var isVisible = false;
Then toggling it to visible is:
isVisible = true;
$(".k-grid-edit").show();
while hiding it is:
isVisible = false;
$(".k-grid-edit").hide();
Basically the variable isVisible stores the state and the template checks it using JavaScript.
NOTE The template might be more compact but I think this is more readable.
One more question (styling) I removed the id from the anchor a in your template since id must be unique and you were setting the same id for all kendoGrid rows.

How to perform click event on an element present in the anchor tag?

<div class="buttonClear_bottomRight">
<div class="buttonBlueOnWhite">
<a onclick="$find('{0}').close(true); callPostBackFromAlert();" href="#">Ok</a><div
class='rightImg'>
</div>
</div>
</div>
In the above code i wanted to click on Ok button present in the anchor tag.But an id is not generated because of which i cannot directly perform a click action. I tried a work around mentioned below.
IElementContainer elm_container = (IElementContainer)pw.Element(Find.ByClass(classname));
foreach (Element element in elm_container.Elements)
{
if (element.TagName.ToString().ToUpper() == "A")
{
element.Click();
}
}
But here elm_container returns null for intial instances due to which we cannot traverse through it. Is there any other easy method to do it ?
Try this...
Div div = browser.Div(Find.ByClass("buttonClear_bottomRight")).Div(Find.ByClass("buttonBlueOnWhite"));
Debug.Assert(div.Exists);
Link link = div.Link(lnk => lnk.GetAttributeValue("onclick").ToLower().Contains(".close(true)"));
Debug.Assert(link.Exists);
link.Click();
Hope it helps!
You can simply Click on the link by finding its text
var OkButton = Browser.Link(Find.ByText("Ok"));
if(!OkButton.Exists)
{
\\Log error here
}
OkButton.Click();
Browser.WaitForCompplete();
Or you can find the div containing the link like,
var ContainerDiv = Browser.Div(Find.ByClass("buttonBlueOnWhite"));
if(!ContainerDiv.Exists)
{
\\Log error here
}
ContainerDiv.Links.First().Click();
Browser.WaitForComplete();

Resources