Protractor can't find button with $ctrl on ng-click - css

I cannot find buttons that have this $ctrl part with protractor.
Example of a button:
<button class="btn btn-primary ng-scope" ng-click="$ctrl.openProfileModal()" ng-if="$ctrl.admin && $ctrl.networkInfo.scenario !== 'simple_mesh'"
ng-disabled="$ctrl.stats['5G'].full && $ctrl.stats['2G'].full"><i class=""></i>Add virtual AP</button>
The reasonable solution seems to be to search with ng-click:
addVAPButton = element(by.css('[ng-click="$ctrl.openProfileModal()"]'))
But it does not work. I've tried it with various comma combinations, searching by class, by ng-if, by xpath, tried adding id, name, other attributes to this button, but nothing helped Selenium find it. I can find other elements from the page that do not have $ctrl by ng-click, name, id, model, so I suspect that there is something about $ctrl that is not compatible with protractor. Any solutions or workarounds to reach this button?
Protractor version:5.3.0
Angular version: 1.5.11

To find the button with text as Add virtual AP you can use the following line of code :
addVAPButton = element(by.css("button.btn.btn-primary.ng-scope > i"))
Note : As the button is an Angular Element you have to wait for the button to be clickable
Update
As an alternative you can try either of the following options :
addVAPButton = element(by.css("button.btn.btn-primary.ng-scope"))
Or
addVAPButton = element(by.xpath("//button[#class='btn btn-primary ng-scope' and contains(.,'Add virtual AP')]"))

Found a way that works with any selector (css, ng-click, id, name, xpath, whatever):
addVAPButton = $("[ng-click=\"$ctrl.openProfileModal()\"]");
browser.wait(protractor.ExpectedConditions.elementToBeClickable(addVAPButton), 10000).then(function(){
addVAPButton.click();})

Related

Can't click on a button, need a solution (userscript for Greasemonkey/Tampermonkey)

I'm trying to click the "Visit" button here:
<a name="claim" href="#" onmousedown="$(this).attr('href', '/sdf/view.php?dsg=45368');"
class="btn-small larg-btn">Visit<i class="fas fa-eye" aria-hidden="true"></i></a>
There many other buttons (same but with different links) on the page, but I need to click only 1 (first link in a row) each time I visit/load the page.
Tried to combine those two solutions (1 and 2) but unfortunately I'm absolutely dumb in it:-)).
Also tried the simpliest thing which works in most cases
(function (){
document.querySelector('selector').click();
But obviously didn't help at all.
Thank you.
The link in your example doesn't have the correct href therefore click() wont have the desired result.
Method 1:
Get the link e.g. querySelector()
Simulate mousedown on the link so page JS changes the URL
Click the link
Method 2:
Get the link e.g. querySelector()
Get the onmousedown attribute
Get the final URL from the above attribute using Regular Expression
Assign the URL to the link
Click the link or open using GM_openInTab/GM.openInTab
Method 3: (not recommanded)
Get the link e.g. querySelector()
Get the onmousedown attribute
Use eval() to run the onmousedown JS on the link
Click the link
Here is an example of the method 1 using CustomEvent()
// get the link using the correct query
const a = document.querySelector('a.btn-small');
if (a) {
// simulate mousedown
const event = new CustomEvent('mousedown');
a.dispatchEvent(event);
console.log(a.href); // not needed, for debuggin only
a.click();
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<a name="claim" href="#" onmousedown="$(this).attr('href', '/sdf/view.php?dsg=45368');"
class="btn-small larg-btn">Visit<i class="fas fa-eye" aria-hidden="true"></i></a>
Using GM.openInTab
const a = document.querySelector('a.btn-small');
if (a) {
const event = new CustomEvent('mousedown');
a.dispatchEvent(event);
GM.openInTab(a.href)
}

Vue.js CSS change button onClick to href not working

In a SinglePageApp, I need to use a <button> tag rather than an <a> tag 5 I am using UKit
the <a> tag would be :
<a type="button" class="uk-button uk-button-link" href="#events"><events</a>
But writing the tag this way , does not work
<button #click="location.href='{{ url('events') }}'" class="uk-button uk-button-link">EVENTS</button>
note : I see an ESLint error .. [js] ';' expected
#webnoob answer is correct , however it seems that it's not working in a single page application : I get a scopelocation undefined error..
SO I am using a method :
<button #click="goToEvents()" class="uk-button uk-button-link">EVENTS</button>
and
methods: {
goToEvents: function () {
location.href='#events'
}
},
To do an onclick with Vue, you would do it like this:
<button v-on:click="location.href=url('events')" class="uk-button uk-button-link">EVENTS</button>
You can also use #click="location.href=url('events')"
Take a look at Vue Event Binding for more information.
If you're within a form and don't want the form to be posted as well, you would need to also add in .prevent so it would become v-on:click.prevent="url('events')"
You only use {{ }} (mustache's) when you're rendering content i.e text. When you're within an attribute which you want to use dynamic values in, you would prefix the attribute with : so, for instance, if you wanted to add some dynamic text in a data attribute, it would become :data-something="myDataProp"

Flex: is it possible to access default `mx:Tree` icons?

I have a bit of a problem, in that I have a tree:
<mx:Tree iconField="#icon" />
That's been fine for a while, but now I want parts of the tree to have their default icons. Now, for reasons I haven't figured out yet, the icon member of the source XML is ignored for branch nodes, and the default is used But for leaf nodes, I must have a valid icon member, or I get an exception. icon="" doesn't work.
Taking a look under the hood, I ran:
trace('The default tree icon: ' + tree.itemToIcon(tree.selectedItem).toString());
which revealed the default to be:
class _TreeStyle__embed_css_Assets_swf_TreeNodeIcon_770392128
which is way too magic string. No thanks. I didn't even try assign that to icon.
Rather than do a screen cap, Gimp edit, and then make it into a custom icon, how do I simply reference the default icon that the platform provides?
Flex 3.5 SDK here.
I think you do over think & with that over complicate everything!
I have not worked with this a long time, but maybe this still could help you a little.From memory I had more complex once as well but have not looked at any of it quiet awhile! One Link of many I used with Tree setup
gallery icon="iconSymbol0AG"
gallery label=" AR - ARGENTINA" src="com/assets/images/countriesFlagsRoundLarge/ar.png"
gallery label=" Mauricio Photography" src="com/assets/images/PageOne/PhotographyBlogs/BlankArtists/AR/TheMauricioBlog.swf"
file label=" Web Site" icon="iconSymbolAR" src="com/assets/images/PageOne/PhotographyBlogs/WebSites/AR/TheCollazosBlog.swf"
gallery
Following Amy's suggestion, I tried:
public var m_icoDefaultLeaf:Class;
private static var m_oDummyTree:Tree;
private static var m_xmlDummy:XML;
...
m_oDummyTree = new Tree;
m_xmlDummy = <dummynode />;
m_oDummyTree.dataProvider = m_xmlDummy;
m_oDummyTree.addEventListener(FlexEvent.CREATION_COMPLETE,
function (evt:FlexEvent):void {
m_icoDefaultLeaf = m_oDummyTree.itemToIcon(m_xmlDummy);
removeChild(m_oDummyTree);
m_oDummyTree = null;
m_xmlDummy = null;
}
);
addChild(m_oDummyTree);
Then I just used icon="m_icoDefaultLeaf" in the XML for the leaves and amazingly, it worked!
Yes, it does have to be that complicated. I had to handle that event, and I had to add the tree as a child of something.
And another thing I tried, was to erase all that code and just use
public var m_icoDefaultLeaf:Class = null;
But that just made a blank icon, not a default.

How to Attach Events to Table Checkboxes in Material Design Lite

When you create a MDL table, one of the options is to apply the class 'mdl-data-table--selectable'. When MDL renders the table an extra column is inserted to the left of your specified columns which contains checkboxes which allow you to select specific rows for actions. For my application, I need to be able to process some JavaScript when a person checks or unchecks a box. So far I have been unable to do this.
The problem is that you don't directly specify the checkbox controls, they are inserted when MDL upgrades the entire table. With other MDL components, for instance a button, I can put an onclick event on the button itself as I'm specifying it with an HTML button tag.
Attempts to put the onclick on the various container objects and spans created to render the checkboxes has been unsuccessful. The events I attach don't seem to fire. The closest I've come is attaching events to the TR and then iterating through the checkboxes to assess their state.
Here's the markup generated by MDL for a single checkbox cell:
<td>
<label class="mdl-checkbox mdl-js-checkbox mdl-js-ripple-effect mdl-data-table__select mdl-js-ripple-effect--ignore-events is-upgraded" data-upgraded=",MaterialCheckbox">
<input type="checkbox" class="mdl-checkbox__input">
<span class="mdl-checkbox__focus-helper"></span>
<span class="mdl-checkbox__box-outline">
<span class="mdl-checkbox__tick-outline"></span>
</span>
<span class="mdl-checkbox__ripple-container mdl-js-ripple-effect mdl-ripple--center">
<span class="mdl-ripple"></span>
</span>
</label>
</td>
None of this markup was specified by me, thus I can't simply add an onclick attribute to a tag.
If there an event chain I can hook into? I want to do it the way the coders intended.
It's not the nicest piece of code, but then again, MDL is not the nicest library out there. Actually, it's pretty ugly.
That aside, about my code now: the code will bind on a click event on document root that originated from an element with class mdl-checkbox.
The first problem: the event triggers twice. For that I used a piece of code from Underscore.js / David Walsh that will debounce the function call on click (if the function executes more than once in a 250ms interval, it will only be called once).
The second problem: the click events happens before the MDL updates the is-checked class of the select box, but we can asume the click changed the state of the checkbox since last time, so negating the hasClass on click is a pretty safe bet in determining the checked state in most cases.
function debounce(func, wait, immediate) {
var timeout;
return function() {
var context = this, args = arguments;
var later = function() {
timeout = null;
if (!immediate) func.apply(context, args);
};
var callNow = immediate && !timeout;
clearTimeout(timeout);
timeout = setTimeout(later, wait);
if (callNow) func.apply(context, args);
};
}
$(document).on("click", ".mdl-checkbox", debounce(function (e) {
var isChecked = !$(this).hasClass("is-checked");
console.log(isChecked);
}, 250, true));
Hope it helps ;)
We currently don't have a way directly to figure this out. We are looking into adding events with V1.1 which can be subscribed to at Issue 1210. Remember, just subscribe to the issue using the button on the right hand column. We don't need a bunch of +1's and other unproductive comments flying around.
One way to hack it is to bind an event to the table itself listening to any "change" events. Then you can go up the chain from the event's target to get the table row and then grab the data you need from there.
You could delegate the change event from the containing form.
For example
var form = document.querySelector('form');
form.addEventListener('change', function(e) {
if (!e.target.tagName === 'input' ||
e.target.getAttribute('type') !== 'checkbox') {
return;
}
console.log("checked?" + e.target.checked);
});

click() on css Selector not working in Selenium webdriver

HTML
<input class="button" type="button" onclick="$.reload('results')" value="Search">
I don't have an id or name for this . Hence am writing
FirefoxDriver driver = new FirefoxDriver();
driver.get("http://....");
driver.findElement(By.cssSelector("input[value=Search]")).click();
But click() is not happening.
Tried
driver.findElement(By.cssSelector(".button[value=Search]")).click();
Tried
value='Search' (single quotes).
these Selectors are working in
.button[value=Search] {
padding: 10px;
}
input[value=Search] {
padding: 10px;
}
i would inject piece of js to be confident in resolving this issue:
first of all locate element using DOM (verify in firebug):
public void jsClick(){
JavascriptExecutor js = (JavascriptExecutor) driver;
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append("document.getElementsByTagName('button')[0].click();");
js.executeScript(stringBuilder.toString());
}
jsClick();
from the retrospective of your element it be like:
....
stringBuilder.append("document.getElementsByTagName('input')[0].click();");
....
Please, note: document.getElementsByTagName('input') returns you an array of DOM elements. And indexing it properly e.g. document.getElementsByTagName('input')[0], document.getElementsByTagName('input')1, document.getElementsByTagName('input')[2]....
,etc you will be able to locate your element.
Hope this helps you.
Regards.
Please use the below code.
driver.findElement(By.cssSelector("input[value=\"Search\"]")).click();
It works for me. And make sure that the name is "Search", coz it is case sensitive.
Thanks
Are you sure that using this CSS-selector (input[value=Search]) on your page you have only one result?
single quotes are missing in your code, the [value=Search] should be replaced with [value='Search'].
first you have to check if the selector u are using will work or not..
If you are using chrome or FF,you can follow these steps,
go to the page where button (to be clicked) is present,
open web console and type in the following and click enter..
$("input[value='Search']")
or
$("input[value='Search'][type='button']")
or
$("input[value='Search'][type='button'].button")
you will get a list of elements which can be accessed using this selector, if that list contains only one element (button that you want to click), then this selector is valid for your use..otherwise u'l have to try some other selector..
If any of the above selector is valid,u'l have to change your code accordingly..
driver.findElement(By.cssSelector("input[value='Search'][type='button'].button")).click();

Resources