Locating the element which is in Shadow DOM using WATIR - ruby

I followed JustinKo's other answer(How to access and interact with Shadow DOM using Watir?) but I don't know how to use it for my requirement here.
here is the text field which I would like to locate. This text_field is coming within the shadow dom as shown below.
<div class="vaadin-text-field-container">
<label part="label" id="vaadin-text-field-label-0">Username</label>
<div part="input-field" id="vaadin-text-field-input-0">
<slot name="prefix"></slot>
<slot name="input">
<input part="value" tabindex="0" aria-labelledby="vaadin-text-field-label-0 vaadin-text-field-input-0" maxlength="512" autocomplete="off" required="">
</slot>
<div part="clear-button" id="clearButton" role="button" aria-label="Clear" hidden="true"></div>
<slot name="suffix"></slot>
</div>
<div part="helper-text" id="vaadin-text-field-helper-0">
<slot name="helper"></slot>
</div>
<div part="error-message" aria-live="assertive" aria-hidden="true" id="vaadin-text-field-error-0"></div>
</div>
<style include="lumo-text-field"></style><style include="lumo-input-field-theme"></style><style include="flow_css_mod_12"></style>
Any specific method which would help me locating this element in Shadow DOM in WATIR?

Related

Integrate ckeditor in asp.net core mvc

I need to integrate an web based html editor in asp.net core project. I downloaded CKEditor and placed the unzipped folder in wwwroot folder.
I have referenced "ckeditor.js" in _Layout.cshtml using following script tag.
<script src="~/ckeditor/ckeditor.js" type="text/javascript">
</script>
Then, I've used following code to display the editor.
<textarea id="editor1" name="editor1">
</textarea>
<script type="text/javascript">CKEDITOR.replace('editor1');</script>
On using these lines of code in the empty About.cshtml of Home Folder, the editor was displayed. But the editor was not displayed when using the same code in another .cshtml file. The Code is given below
<div class="panel">
<div class="panel-heading border">
Create User
</div>
<div class="panel-body">
<div class="row no-margin">
<div class="col-lg-12">
<form asp-action="Edit" class="form-horizontal bordered-group" role="form">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<input type="hidden" asp-for="_id" />
<div class="form-group">
<label asp-for="Subject" class="col-sm-2 control-label"></label>
<div class="col-sm-10">
<input asp-for="Subject" class="form-control" />
<span asp-validation-for="Subject" class="text-danger" />
</div>
</div>
<div class="form-group">
<label asp-for="MailFrom" class="col-sm-2 control-label"></label>
<div class="col-sm-10">
<input asp-for="MailFrom" class="form-control" />
<span asp-validation-for="MailFrom" class="text-danger" />
</div>
</div>
<div class="form-group">
<label asp-for="Body" class="col-sm-2 control-label"></label>
<div class="col-sm-10">
#* CKEDitor *#
<textarea id="editor1" name="editor1">
</textarea>
</div>
</div>
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<input type="submit" value="Update" class="btn btn-default" />
</div>
</div>
</form>
</div>
</div>
</div>
</div>
<script type="text/javascript">CKEDITOR.replace('editor1');</script>
Why is the editor not displayed in another cshtml file?
I've also faced the same problem while integrating CKEditor in aps.net mvc project. After trying to determine the error I found that the Layout of the page is different. You may have the same problem.
Use id attribute and use a hash on the name.
<script type="text/javascript">CKEDITOR.replace('#editor1');</script>

Dollar sign followed by a curly bracket inside widget html

I am currently on the Helsinki Release
Cannot understand the purpose of dollar sign and curly braces inside label tag
<label class="control-label" for="inputSuccess">${Location}</label>
The full html of the weather widget:
<form class="form-inline well">
<div class="form-group" ng-class="{'has-error': (c.errorMessage), 'has-success': (c.channel)}">
<label class="control-label" for="inputSuccess">${Location}</label>
<input type="text" class="form-control" id="weatherInput" placeholder="{{::data.enterLocMsg}}" ng-model="c.data.place">
<button type="submit" class="btn btn-default" ng-click="c.getWeather();">${Go}</button>
<span class="help-block" ng-bind="c.errorMessage" ng-if="c.errorMessage"></span>
</div>
</form>
<div class="panel panel-default" ng-if="c.channel">
<div class="panel-body">
<p>${Location}: {{c.channel.location.city}}, {{c.channel.location.region}} {{c.location.country}}</p>
<p>${Temperature}: {{c.channel.item.condition.temp}}</p>
<p>${Condition}: {{c.channel.item.condition.text}}</p>
<p>{{c.channel.item.condition.date}}</p>
</div>
</div>
From ServiceNow Product Dokumentation
Use the HTML template to internationalize strings in a widget.
Writing text as ${message} is the equivalent of writing ${gs.getMessage("message")} in other parts of the system, but written as a more legible shorthand.

XPath find child, where another child of the same node has specific value

I have 4 other elements the same as below though they differ in title
<div id="r7695cf6b-f4a79" class="featureFoo ">
<div class="overview">
<h3 class="title">My Library</h3>
<p class="description">Some description</p>
</div>
<div class="foo">
<form>
<div id="ra41984bc58005" class="switch label-position-right non-required" aria-describedby="">
<input name="fooEnabled" type="checkbox" id="r14e560d0-bfbc-476a-a066-cbb3c043006c" checked="" class="">
<div class="foo-switch">
<div class="indicator"></div>
</div>
<span class="error" title=""></span>
</div>
</form>
</div>
</div>
I am trying to retrieve the nonhidden input element and to see if it is checked. I have this xpath
$x("//div[contains(#class, 'featureFoo')][./div/h3[text()='My Library']]//input[contains(#name,'fooEnabled')]")
which works in the Chrome console but it does not work in Ruby Cucumber's find() method
find(:xpath, "//div[contains(#class, 'featureFoo')][./div/h3[text()='My Library']]//input[contains(#name,'fooEnabled')]")
Is there more conversion that needs to be done to the xpath so it will work in cucumber's find() or could there be a better approach to this?

Wget post data with text box that has randomly generated value?

I'm trying to use Wget to log in to my router and make a complete mirror of all the pages. The problem is, the router login page does not use the traditional "user" & "pass" ID for the text fields. It has a 'Password' and 'VmWpsPin' field. The ID for the 'Password' field is randomly generated every time the page is loaded/refreshed/requested. Below is the source code of the relevant part of the router page:
<body lang="en" class="superhubGUI" onload="javascript:Init()">
<div class="globalHeader">
<div id="nav">
<div id="logo">
<h1 id="header">Super Hub</h1>
</div>
<div id="buttons">Router Status
</div>
</div>
</div>
<div id="content">
<div id="container">
<div id="main">
<div class="panel noTitle" style="*padding:38px 30px 0px 30px">
<div id="login" class="inner">
<div class="inner-section">
<h2>Welcome to your Virgin Media Super Hub 2ac</h2>
<div id="signInForm">
<form action="/cgi-bin/VmLoginCgi" method="POST" name="signIn1" id="signIn">
<h2 id="loginTitle">Sign in to view and change your settings</h2>
<div class="field formField noHint username clearfix">
<label for="username"></label>
</div>
<div style="position:relative;top:-20px;" class="field formField noHint password clearfix">
<label for="password">Settings Password</label>
<input type="password" autocomplete="off" value="" maxlength="15" class="name required onefiftyPX inactive" name="KsCAqiihZb" id="password" onkeypress="handleKeyPress(event)" />
<div style="position:relative;left:-10px;" class="tooltip">
<img style="position:absolute; top:10px;" src="../images/toolTipButton.png"><span>Password can be found on the base of your Super Hub</span>
</div>
</div>
<div style="position:relative;top:-25px;" class="field formField noHint password clearfix">
<label for="password">WPS PIN</label>
<input type="text" autocomplete="off" value="" maxlength="15" class="name required onefiftyPX inactive" name="VmWpsPin" id="WpsPin" onkeypress="handleKeyPress(event)" />
<div style="position:relative;left:-10px;" class="tooltip">
<img style="position:absolute; top:10px;" src="../images/toolTipButton.png"><span>WPS PIN can be found on the base of your Super Hub</span>
</div>
</div>
<div>
Sign In
</div>
</form>
<p>
<span style="font-weight:bold;">Don't know your password?</span>
<br/>You'll find your default password on the bottom of your Super Hub.
</p>
</div>
</div>
</div><span class="pFoot"> </span>
</div>
</div>
My question is, how can I use Wget to login to the router when the ID changes at every request, is there somehow a way to request the page, parse the value out and then submit the form using something like --keep-session?
Or is there an alternative solution outside of Wget to automate the process? Any help is much appreciated.

Knockoutjs default loader doesn't show up on first click

I'm using a knockoutjs extension to place a loader on top of an element that is loaded from an ajax request so that a loading gif is show while the request is executing.
The fiddle is very basic:
It loads a list of avatars and shows the loading image while the ajax
request is executing.
Then, when you click an avatar, it's details
are loaded into another placeholder and a loading icon is also shown
while the request is executing.
The problem is, the very first time I click on an avatar, the loading icon isn't shown but all subsequential clicks works.
What am I missing here?
Thanks!
The issue that you are seeing is related to having both with and your custom binding on the same element. When the value is null, the with binding clears the child elements. This removes your loader (although it has already been copied off as part of the "template" used by the with binding), but it is put back when you populate infos. Having them on the same element also means that the bindings fires twice (once from changing infos and once from updating isAvatarLoading.
The easy way to fix this one is to split out the bindings like:
<div class="avatar" style="margin-left: 55px;" data-bind="loadingWhen: isAvatarLoading">
<div data-bind="with: infos">
<div data-bind="text: firstName"></div>
<div data-bind="text: lastName"></div>
<div data-bind="text: age"></div>
<div data-bind="text: description"></div>
<div style="margin-left: 55px;" id="" data-bind="with: image">
<img data-bind="attr: { src: Url }" />
<div data-bind="text: Description"></div>
</div>
</div>
</div>
If you don't want to add another element, then you could use the containerless with syntax like:
<div class="avatar" style="margin-left: 55px;" data-bind="loadingWhen: isAvatarLoading">
<!-- ko with: infos -->
<div data-bind="text: firstName"></div>
<div data-bind="text: lastName"></div>
<div data-bind="text: age"></div>
<div data-bind="text: description"></div>
<div style="margin-left: 55px;" id="" data-bind="with: image">
<img data-bind="attr: { src: Url }" />
<div data-bind="text: Description"></div>
</div>
<!-- /ko -->
</div>
Sample: http://fiddle.jshell.net/rniemeyer/75Lyn/

Resources