Handling Shadow Dom with Watir - watir

How can I handle elements that are inside iframe which are again inside a shadow Dom using watir 7.2?
Something like this:
<div id="test">
#shadow-root (open)
<div id= "test1">
<iframe id= "iframe">
<input id = "text field">
Code-
shadow_host=#browser.div(id: 'test')
shadow_root=shadow_host.shadow_root
iframe= shadow_root.iframe(id: 'iframe').wai_until(&: present?)
iframe.text_fied(id: 'text field').set(params[:expiry] ||12345)
Please let me know what mistake I am doing?

Related

What is the best way to grab this input element? Can not use attr values

I have a app the creates forms dynamically. In the e2e tests, the e2e creates the form and after the test form will be deleted from the db.
This means I can not use class, ids, or data attribute values because their values are dynamically generated. ie: <div id="input_1642" class="input_1642">. Being the form is created by e2e and destroyed after the test is done, there is no way for me to know their values and they will not persist.
For the following html, in which the only unique value I really have is the required input in <span style="white-space: pre-wrap; overflow-wrap: break-word;">required input</span>
Using Playwright, and not being able to use class, id, or data attribute values, what is the cleanest way to grab (selector) the input so I can page.fill()?
I was hoping to avoid having using Xpath
<div id="input_1642" class="input_1642">
<div>
<div>
<div class="ant-row ant-form-item" style="row-gap: 0px;">
<div class="ant-col ant-form-item-label ant-form-item-label-left">
<label for="input_1642" class="ant-form-item-required" title="">
<span>
<span style="white-space: pre-wrap; overflow-wrap: break-word;">required input</span>
</span>
</label>
</div>
<div class="ant-col ant-form-item-control">
<div class="ant-form-item-control-input">
<div class="ant-form-item-control-input-content">
<span>
<span>
<input formbuilderhiddenfrom="" data-cy="form_item_input_1642_3" data-navigate="false" id="input_1642" class="ant-input align-input-items" type="text" value="">
<span></span>
How about you use a partial selector like this:
page.fill('[data-cy*="form_item_input_"]', 'some text')
To pinpoint the correct element, you can further use the Nth Selector
page.fill('[data-cy*="form_item_input_"] >> nth=0', 'some text')
According to the docs, you can find the element by the text of its label.
You have a label for that input. So you could try something like:
await page.locator('text=required input').fill('some text');

express interprets JADE unexpectedly when using a(href)

In an express app I have a Jade file that looks like this
each tweet, index in tweetData
///some variable declarations
a( class="fancybox" rel="group" href=tweet.media_url tweetLink=tweetLink data-widgetIndex=widgetIndex title="default text" profile_image_url=tweet.profile_image_url)
img(src=tweet.media_url alt="" width="150" height="150")
div(id=widgetIndex, style="display:none")
div(style="min-height:200px") Hello world
div(style="float:left;width:52px;height:100%; display:inline;margin-right:5px")
a(href="#") //<---- this causes trouble!!!!!
img(src=tweet.profile_image_url, style="width:52px;height:48px;background:#bfb;")
div(style="height:48px;background:#bfb;") BALLS
If you look closely, a(class="fancy box ...) is interpreted multiple times for each time through the loop. (It should only be once per time through loop.)
<a class="fancybox" profile_image_url="http://pbs.twimg.com/profile_images/378800000365890826/c04bf726e47f3eda2116b5249e623a43_normal.jpeg" title="default text" data-widgetindex="widget0" tweetlink="http://twitter.com/Sjaakvdvoort/status/undefined" href="http://pbs.twimg.com/media/BXM0sjpCUAAEHOr.png" rel="group">
<img width="150" height="150" alt="" src="http://pbs.twimg.com/media/BXM0sjpCUAAEHOr.png"></img>
</a>
<div id="widget0" style="display:none">
<a class="fancybox" profile_image_url="http://pbs.twimg.com/profile_images/378800000365890826/c04bf726e47f3eda2116b5249e623a43_normal.jpeg" title="default text" data-widgetindex="widget0" tweetlink="http://twitter.com/Sjaakvdvoort/status/undefined" href="http://pbs.twimg.com/media/BXM0sjpCUAAEHOr.png" rel="group"></a>
<div style="min-height:200px">
<a class="fancybox" profile_image_url="http://pbs.twimg.com/profile_images/378800000365890826/c04bf726e47f3eda2116b5249e623a43_normal.jpeg" title="default text" data-widgetindex="widget0" tweetlink="http://twitter.com/Sjaakvdvoort/status/undefined" href="http://pbs.twimg.com/media/BXM0sjpCUAAEHOr.png" rel="group"></a>
<div style="float:left;width:52px;height:100%; display:inline;margin-right:5px">
<a class="fancybox" profile_image_url="http://pbs.twimg.com/profile_images/378800000365890826/c04bf726e47f3eda2116b5249e623a43_normal.jpeg" title="default text" data-widgetindex="widget0" tweetlink="http://twitter.com/Sjaakvdvoort/status/undefined" href="http://pbs.twimg.com/media/BXM0sjpCUAAEHOr.png" rel="group"></a>
...
<div style="height:48px;background:#bfb;">
BALLS
</div>
</div>
</div>
</div>
If I comment out the a(href="#") then those extra a(class="fancy box") elements are not rendered. What gives?
I believe the underlying problem was I had an anchor tag within an anchor tag. I had set up this structure because I actually use jquery to grab the inner anchor tag and display it elsewhere (in a lightbox). If I make the inner anchor tag a cousin (not a descendent) of the outer anchor tag the Jade is interpreted by the outer.

nested template rendering in backbone.js

I have a template like
script type: "text/template", id: "list-template", '''
<div class="display">
<div id="list-name"><%= name %></div>
<span class="list-destroy"></span>
</div>
<div>
<ul id="ul-cards">
</ul>
</div>
<div class="edit">
<input class="list-input" type="text" value="<%= name %>" />
<input id="btnEdit" type="button" value="Save" class="primary wide js-add-list" />
<input id="hdnListId" type="hidden" value="<%= listId%>" />
</div>
<form class="add-list-card js-add-list-card clearfix">
<textarea placeholder="Add card" class="new-card"></textarea>
<input type="button" value="Add" class="primary js-add-card">
<a class="app-icon close-icon dark-hover cancel js-cancel-add-card" href="#" id="closeCard"></a>
</form>
'''
in this template i have <ul id="ul-cards"> element in which i want to render another template which display list inside this ul.
this template is :
script type: "text/template", id: "card-template", '''
<div>
<span class="card-name"><%= name %></span>
</div>
'''
is it possible or i have to do it in another way?
please help me if anyone have idea.
thanks in advace.
it is worked but still i have one problem in data display in
<ul id="ul-cards"> there sholud be 2 as per records in my database but it will display only 1 . data fetch properly but display only last data.
There are two ways to do this: the DOM way and the template way.
The DOM way involves adding your views using DOM methods: you have your ListView and your CardView; the ListView invokes individual CardViews that fill in the ListView's element.
The template way requires that you remember this: backbone's views are policy frameworks, not policy templates. Render doesn't have to render into the DOM. You can use render() to return a string, for example. If your event manager is on the ListView object only (possible; I've done this), then you can have ListView invoke "the resulting array of an array of CardView renders" and insert that directly into ListView's template. This is actually faster, as you only require the browser to analyze the entire ListView HTML blob once, when it's inserted into the innerHTML of the parent DOM object.

Multiple Foursquare 'save' buttons on one page

I am working on a site that displays a list of venues and would like to add a Foursquare 'save' button for each venue in the list. Is it possible to show multiple Foursquare 'save' buttons on a single page? I've tried creating multiple vCard blocks (one for each venue) and inserting a 'save' button in each block but the locations are not being picked up.
After inspecting the source of the widgets.js and widgets.asyncbundle.js I discovered that setting thedata-context atribute of the 'Save to Foursquare' button to the ID of the VCard will link these two. Like so:
<div id="hcard-Station-Amsterdam-Centraal" class="vcard">
<span class="fn">
<span class="given-name">Station Amsterdam Centraal</span>
</span>
<div class="adr">
<div class="street-address">stationsplein 15</div>
<span class="locality">Amsterdam</span>,
<span class="region">Amsterdam</span> ,
<span class="postal-code">1012AB</span>
</div>
</div>
<div id="hcard-Jaarbeursplein" class="vcard">
<span class="fn">
<span class="given-name">Jaarbeursplein</span>
</span>
<div class="adr">
<div class="street-address">Jaarbeursplein</div>
<span class="locality">Utrecht</span>,
<span class="region">Utrecht</span>,
<span class="postal-code">3521AL</span>
</div>
</div>
Save to foursquare
Save to foursquare
But for the fact that this isn't documented, it may be changed in the near future.
Try this with "data-vid":
<!-- Place this anchor tag where you want the button to go -->
<br />
All In PartyRadio StudioSave to foursquare
<br />
Sing Sing Music HallSave to foursquare
<br />
Retro KlubSave to foursquare
<br />
Tisza DokkSave to foursquare
<br />
Zöld Zsiráf KultúrpartSave to foursquare
<!-- Place this script somewhere after the anchor tag above. If you have multiple buttons, only include the script once. -->
<script type='text/javascript'>
(function() {
window.___fourSq = {"uid":"606"};
var s = document.createElement('script');
s.type = 'text/javascript';
s.src = 'http://platform.foursquare.com/js/widgets.js';
s.async = true;
var ph = document.getElementsByTagName('script')[0];
ph.parentNode.insertBefore(s, ph);
})();
</script>
The in-progress docs for the save-to-foursquare widget are accessible # https://developer.foursquare.com/overview/widgets. They'll be cleaned up over time, but should be good enough to help this and future widget-related questions =).
In particular, documentation about the "data-context" attribute you need will be pushed to the linked page soon.

change text on button using jquery mobile.

I would like to change text on button using jquery mobile. It works if I change data-role to none, but then I lose formatting.
<fieldset class="ui-grid-a" data-inline="true">
<div class="ui-block-a"><button class="cl_button1" type="submit"
data-theme="c" data-icon="home" data-iconpos="top">Click Me</button>
</div>
</fieldset>
$('.cl_button1').val('some text');
Another posting suggested this, but it did not work.
$("cl_button1 .ui-btn-text").text("some text");
Using Firebug I found that the HTML markup created by jQuery Mobile is the following:
<fieldset data-inline="true" class="ui-grid-a">
<div class="ui-block-a">
<div data-theme="c" class="ui-btn ui-btn-icon-top ui-btn-corner-all ui-shadow ui-btn-up-c" aria-disabled="false">
<span class="ui-btn-inner ui-btn-corner-all">
<span class="ui-btn-text">some text</span>
<span class="ui-icon ui-icon-home ui-icon-shadow"></span>
</span>
<input type="hidden" value="">
<input type="hidden" value="">
<input type="hidden" value="">
<button data-iconpos="top" data-icon="home" data-theme="c" type="submit" class="cl_button1 ui-btn-hidden" aria-disabled="false">Click Me</button>
</div>
</div>
</fieldset>
You can see that the ui-btn-hidden class has been added to the origional <button> element and the display of the button is actually rendered through the use of the <span> tags above the <button> tag.
So to change the text for this jQuery Mobile rendered element you would use a selector like this:
$('.cl_button1').siblings('.ui-btn-inner').children('.ui-btn-text').text("some text");
Or if you wanted to change the button's text on click you can do this:
$('.cl_button1').bind('click', function () {
$(this).siblings('.ui-btn-inner').children('.ui-btn-text').text("some text");
});
Here is a jsfiddle for demonstration: http://jsfiddle.net/SfySk/1/
All,
The above solutions do not seem to work with JQM 1.1.1. A very simple way of doing this is to call.
$('.cl_button1').text('some text').button('refresh');
As per http://jquerymobile.com/test/docs/buttons/buttons-methods.html, there are only three methods you can call on a button. This should keep the internal state of your button consistent with the JQM UI adornment, and be more robust against changes to the way buttons are made 'pretty' in the future.
in jqm version 1.4.5, after initialization
$('#btn_input').parent().contents().filter(function(){
return this.nodeType === 3;
}).replaceWith('New Text');
It works without destroying binded events.
When you said this didn't work:
$("cl_button1 .ui-btn-text").text("some text");
You forgot the . before cl_button to indicate that you are trying to select a class
I don't see .ui-btn-text anywhere being used as a class
I got your code to work using this:
$('.cl_button1').text('some text');
Test Here: http://jsfiddle.net/S9asF/
A better solution is to refresh the page:
$(currentPage).trigger('create');
$(currentPage).page();
$('#buttonx').children('.ui-btn-inner').children('.ui-btn-text').text("Some Text");

Resources