Sizzle text equals - sizzle

With the Sizzle selector engine, is it possible to find buttons with the exact text?
For example, button:contains('Remove Document') will match any buttons that have the text "Remove Document" but I need it to not match buttons that say "Don't Remove Document". Is there a selector that will match the whole text, start to finish?

You need to use filter there :
$("button").filter(function(){
return $(this).text().trim()==='Remove Document';
});
If you really want to have it in one sizzle selector string, starting from adeneo's answer and completing it, you may use
button:contains("Remove Document"):not(:contains("Don"))

You can put :contains inside :not to not match something :
$("button:not(:contains(Don't Remove Document))")
FIDDLE

Related

page.click use value attribute as selector?

Problem:
The selector might randomly change due to various reasons, therefore, using the selector doesn't guarantee success all the time. Here is my code with the selector.
await page.click('body > div.api-container > div > div.clearAll > form > input[type="submit"]:nth-child(3)');
Is it possible to instead use page.click to click an element based on the "value" attribute? Here is the HTML:
<input name="submit" type="submit" value="Accept">
As you can see the value will always equal "Accept" and it would be easier to search the page and click the matching element.
Based on my research it looks like page.$x(expression) would work but I'm unsure how to write the expression.
Any help is greatly appreciated!
Is it possible to instead use page.click to click an element based on the "value" attribute?
It is, and you already have a variety of that in your initial selector, I'm talking about input[type=submit]. Instead of type there can be any other property of an element, including value:
await page.click('input[value="Accept"]');
await page.click('input[name="submit"]');
You could even omit type of element and search by its property only: '[value="Accept"]', but keep in mind that this approach can potentially find several results, and only the first of them will be clicked (quite possibly, not the one you had in mind), so do test selector in a real browser's console first.

How to get the text of a menu item with its ID

I have an old visual prolog project in which I have to change the text of a menu during runtime.
This is what I've done to change the text:
menu_setText(Win, id_menu, NewMenuText)
This works fine, however, when I want to enable/disable this menu, the following does not work (meaning the menu item doesn't change its state):
menu_Enable(Win, id_menu, b_true)
After some search, I found that:
Under MS-Windows, submenus can not be referred to by a resource identifier. If the menu entry for a submenu, needs to enabled, disabled, checked or have the text changed. it is necessary to use a special versions of the menu_Enable, menu_Check and menu_SetText predicates, which specify the text of the menu entry instead of the constant.
menu_Enable(WinHandle, String, BOOLEAN)
menu_Check(WinHandle, String, BOOLEAN)
menu_SetText(WinHandle, String, NewString)
The weird thing is that in my case, menu_setText works just fine with the constant where menu_Enable requires the text itself. (yes I tested menu_Enable with the initial text of the menu item, but when the text changes then everything breaks)
Here comes my question:
How can I enable/disable a menu when I know its ID but not its name ?
If not possible directly, how can I get the current name of a menu when I know its ID ?
In case this helps, this project is opened and compiled with VIP52 (since before the year 2001).
I finally found a workaround that solves my problem, but I'm still not really satisfied, so if anyone comes up with a better answer, I'll take it !
I declared:
txt_menu(menu_tag,string)
And then called:
txt_menu(id_menu, MenuText),
menu_setText(Win, MenuText, NewText),
retractAll(txt_menu(id_menu,_)),
assert(txt_menu(id_menu,NewText)),
menu_Update(Win)
whenever I have to change the text of a menu item, and this can easily be transformed into a menu_setTextById predicate as such:
menu_setTextById(Win, MenuId, NewText):-
txt_menu(MenuId, MenuText),
menu_setText(Win, MenuText, NewText),
retractAll(txt_menu(MenuId,_)),
assert(txt_menu(MenuId, NewText)),
menu_Update(Win).
with the usage:
menu_setTextById(Win, id_menu, "My new text menu").
Noted that if I ever have the need to have several windows with menus, I'll have to add the Window Id to my txt_menu clause.
The main problem with this workaround is that I can't use & in the new text menu because if my menu has "&Menu" as text (meaning that M will be underlined), then trying to use menu_setText(Win,"&Menu","New Menu") will break because "&Menu" is not found.
So I'd need to remove any ampersand from the string before trying to use it in such predicates.

How to select an option from a dropdown list using chromeless API?

I am using chromeless API (https://github.com/graphcool/chromeless)
How can I select an option from a dropdown list?
Specifically I want to select last option having value="other".
My HTML is:
You could achieve this with the evaluate() method which lets you evaluate any Javascript within the browser-context of any page you load:
await chromeless
.goto('http://yourwebsite.com/yourpage')
.evaluate(() => {
select = document.querySelector('select.decline-form-select')
select.value = 'other'
})
Or, specifically select whatever the last item is in the select list:
await chromeless
.goto('http://yourwebsite.com/yourpage')
.evaluate(() => {
document.querySelector('select.decline-form-select option:last-child').selected = true
})
It can be done without the evaluate() method, too, albeit in a somewhat convoluted way. Avoiding evaluate() is useful when it is unknown exactly which events have to be triggered upon change, for the web application to work.
await chromeless
.click('#the-select-element')
.type('First characters of description text of desired option', '#the-select-element')
.click('#the-select-element option[value="the-matching-value"]')
Or using the example posted in the question:
await chromeless
.click('select.decline-form-select')
.type('Oth', 'select.decline-form-select')
.click('select.decline-form-select option[value="other"]')
Selecting an option using native Chromeless commands involves first clicking the select element, then typing text to select the desired option, based on the visible text content of the option (the first few characters that unambiguously identify the option should be enough), and then clicking the desired option element. Since it is not possible to find the option element by text content using css selectors, the element must be selected by some other means – e.g. value or ordinal number.
Sending arrow key presses instead of typing characters to select the option might work, but I found in my testing that using the press() method was buggy. (A tab with Chrome settings would open randomly while executing tests that used press() to send either the return or the space key.)
All this said, I was unable to make tests run reliably with Chromeless. There seemed to be problems related to scrolling elements into view or not. While the webdriver-based systems http://webdriver.io, http://nightwatchjs.org and https://www.npmjs.com/package/selenium-webdriver are a bit more complicated to set up and code for, it might be worth the effort in order to get better reliability.

How to avoid spacing in class name

Currently, I am automating a web page using Watir-webdriver with page-objects. Here I want to check a class name if checkbox checked. I need to check infra01 and checked is present if unchecked infra01 and unchecked exists or not.
<span class="infra01 infrastructure checked"></span>
<span class="infra01 digitinline unchecked"></span>
Please help how to proceed using regular expression. Also please help me how to proceed the class name with spacing.
Not sure about the page object part, but you don't necessarily need to use a regular expression. You can use the attribute_value method to get the value of class attribute in the span tag and check to see if "unchecked" is included in the returned string:
browser.span.attribute_value("class").include? "unchecked"
try to proceed with regexp:
browser.span(:class => /#{Regexp.escape("infra01 infrastructure checked")}/).when_present.click
If it possible to use "if" 1st element unchecked "else" click 2nd element

Watir : How do we capture the subitems displayed by doing mouseover on a particular item

I am trying to work with mouseover on a particular Item in my application by using the following command
{
ie.text_field(:xpath, "//a[contains(text(),'Deal')]").fire_event('onmouseover')
}
On doing mouseover on a item, two subitems are displayed.
Is there any way to capture the sub items which are part of the Item by doing mouseover with which we can report that our test is pass or fail.
Please suggest.
Additional Information :
If we take example,On the StackOver flow page, If i do mouseover on my name, i get a window where i see activity, privileges, Logout and other stuff. This is really what i was looking for. Is there a way to capture the items displayed on the window on doing mouseover.
I also tried to capture the subitems with the following :
{
text=ie.text_field(:xpath, "//a[contains(text(),'Deal')]").fire_event('onmouseover')
puts(text.inspect)
}
On doing this "text" value is displayed as 'nil'.
My general tactic for such things is a combination of using IRB and the IE Developer tool, or Firebug.
using IRB, type out (or cut and paste) the watir statement to fire the onmouseover command to the proper element on the page.
Then have the developer tool rescan the DOM (there's a little refresh icon you can click) The use the tool to point to an element to point to one of the items in the stuff exposed by the onmouseover. Using the info from that, you can then figure out how to address those elements to get the text from the proper div, etc.
If I do that here to the info that opens up when I float the mouse over my name I can find out that it is a table of class "profile-recent-summary" Furthermore I can then look at the way the table is made up and see for example that the 'today' reputation value is in the second cell on that row.. The row also has the text 'reputation' in it.. so
browser.table(:class, 'profile-recent-summary').row(:text, /reputation/).cell(:index, 2).flash
Should flash the cell I want (index might be 1 if using firewatir or webdriver) I can then replace the .flash with something else like .text if I want to get the text from that cell (which is actually inside a link that sits in the cell)..
without seeing your code, I would 'inspect' the element that you are trying to verify and when_present (text) assert that its true

Resources