Access frame via "relative=up" with Selenium & Ruby - ruby

Recently I've used command "selectFrame > relative=up" in Selenium IDE to switch between nested frames. Since i've decided to rewrite all code in Selenium and Ruby, i can't find this command analog for mentioned language.
I can't select frame by name because it different after any reload. Other frame attributes are:
iframe id="ext-comp-1465" name="ext-comp-1465" frameborder="0" src="/5005700001V96Ub/e?retURL=%2F5005700001V96Ub&isdtp=vw&cancelURL=%2F5005700001V96Ub&nonce=a37ade0829c6d08539a765cd370dff0766cd596851439e853d68a60e9d7c28d0&sfdcIFrameOrigin=https%3A%2F%2F*************.com" class=" x-border-panel" style="left: 0px; top: 0px; width: 329px; height: 641px;"></iframe
Please advise how i can get to this frame using "relative=up" option or other frame attributes. Thanks in advance.

Try the following,
driver.switch_to.frame "ext-comp-1465"
or
driver.switch_to.frame driver.find_element(id: 'ext-comp-1465')
or
driver.switch_to.frame driver.find_element(name: 'ext-comp-1465')
or
driver.switch_to.frame driver.find_element(xpath: '//iframe[starts-with(#id,"ext-comp-"] ')

Final solution:
frames = #driver.find_elements(:xpath, '//iframe[starts-with(#id,ext-comp-)]')
#driver.switch_to.frame frames[1]

Related

Shoes Clipboard Access from App

I am having problems getting the clipboard contents from within an app, using ruby shoes.
I have tried the solution Shoes problems: clipboard and scroll bar, which does not work, as well as several other self-made solutions. According to http://shoesrb.com/manual/App.html, these attempts should work. My current attempt is:
def someFunction
#theapp = Shoes.app(title: "AppName", width: 400) {
#clip = edit_box width: 400, height: 400, text: app.clipboard do
app.clipboard = #clip.text
end
}
end
As well as referencing app.clipboard, I have attempted Shoes.clipboard, Shoes.app.clipboard, self.clipboard, and #theapp.clipboard, all of which have failed. Some of them have even caused a blank window to appear without any elements in it. How can I fix this strange issue?
Try capturing the content of the edit_box in a block parameter:
Shoes.app do
edit_box do |clip|
app.clipboard = clip.text
end
end
Your question helped us to fix a bug in the upcoming release of Shoes 4. Thanks :)

How to print table headers on all but the first page in freemarker

I've revised my original question because I'm new and can't reply to my own just yet... but here is my issues re-written, with more coding:
I'm using this as part of NetSuite, which is an accounting/ordering/CRM tool our company uses. We are allowed to customize our own estimates by using their form creation tool, which takes a combination of freemarker, html and xml to create our estimates.
I've designed a nice looking estimate and within this estimate I can call variables from the database. Basically shipping/billing info, items on the estimate and today I was able to add PAGE NUMBERS (Page 1 of 5 or Page 3 of 5) and place them at the bottom utilizing a FOOTER. However I wanted to also do this so that if my estimates ran multiple pages, I could print a header at the top so you'd see "Quantity, description, price" as I explained.
Now... I'm not exactly sure what the macros are for, this was how I wrote my page numbers and put them on the footer, which i'll show the code for in a bit.
I wanted to do something similar so that I could say "If we're not looking at page 1, print THIS header, but IF we're looking at Page 1, DONT print a header" so I figured i could do that page = page + 1 so it kept increasing. This idea WORKS in other parts of my estimate (for example, every item listed is on a seperate line on the estimate, and i actually print a line number, using that method, but that runs within its own routine later in the system via the LIST function)....
so any help getting this to work for my HEADER would be appreciated. I was hoping I could just do something simple such as "page = PAGENUMBER" but i can't utilize the built-in pagenumber variable for some reason, it doesnt quite work that way... here is what I have, in a simplified manor:
<!--?xml version="1.0"?-->
<pdf>
<head>
<style type="text/css">
STYLES HERE
</style>
<macrolist>
<macro id="footer">
<hr></hr>
<table border="0" width="100%">
<tr>
<#setting time_zone="America/New_York">
<td align="left">${.now}</td>
<td align="right">Page <pagenumber/> of <totalpages/></td>
</tr>
</table>
<hr></hr>
</macro>
</macrolist>
</head>
<body footer="footer" footer-height="12mm">
REGULAR HTML HERE FOR OUR COMPANY
<#if (record.item?size > 0)>
<table class="border" width="100%" cellpadding="2">
<#assign line = 0>
<#list record.item as item>
<#if item_index==0>
<tr>
<td width="5%" class="border4" valign="center"><b>Ln #</b></td>
<td width="5%" class="border4" valign="center"><b>Qty</b></td>
<td width="66%" class="border4" valign="center"><b>Description</b></td>
<td width="12%" class="border4" valign="center" align="right"><b>Unit Price</b></td>
<td width="12%" class="border5" valign="center" align="right"><b>Ext. Price</b></td>
</tr>
</table>
<table width="100%" cellpadding="7">
</#if>
<tr>
<#assign line = line + 1>
<td width="5%" valign="top">${line}</td>
<td width="5%" valign="top">${item.quantity}</td>
<td width="71%" valign="top">${item.description?html}<br /><i>Manuf. Part #: ${item.item.text}</i></td>
<td width="12%" valign="top" align="right">$${item.rate}</td>
<td width="12%" valign="top" align="right">$${item.amount}</td>
</#if>
</tr>
</#list>
</table>
</#if>
MORE HTML FOR OUR COMPANY HERE
</body>
</pdf>
So with all that said, any thoughts as to how I can utilize that "LN #, QTY, DESCRIPTION, UNIT PRICE, EXT. PRICE" as headers on pages 2 and on? (Page 1 has our letterhead at the top and some other html coding for our company)
As Yvan noted, this is not a freemaker question, but actually a bfo question. And as Shaun noted you can use the CSS id selector of #pagen to set header/footer for a given page. The problem with this is that all the existing documentation I've seen shows that if you use the #pagen CSS selector, then you have to define the CSS for every other page as well. So for example ...
/* If */
#page1 {
header: empty-header;
header-height: 0px;
}
/* Then */
#page2, #page3, #page4, ... #pagen {
header: default-header;
header-height: 10mm;
}
You basically have to guess what the maximum page size will be and add a CSS selector for each and every one of page. It might be safe enough to go up to 10 or something, because honestly whose going make an 11 page order, right?
Well if this doesn't sit right with you or you just don't like hard-coded limitations like this, then I believe I have an alternative. If one defines the default header on the <body> tag. Then define the #pagen CSS selector for just the page (or pages) you need (i.e. page 1 in your case,) but use the !important CSS property you'll get the desired results. For example this should do the trick...
<!--?xml version="1.0"?-->
<pdf>
<head>
<style type="text/css">
#page1 {
header: empty-header !important;
header-height: 0px !important;
}
</style>
<macrolist>
<macro id="empty-header">
<!-- Nothing to look at here -->
</macro>
<macro id="default-header">
<!-- Header HTML for all but first page -->
</macro>
</macrolist>
</head>
<body header="default-header" header-height="12mm">
<!-- Page body HTML -->
</body>
</pdf>
I don't know what macro and macrolist are (that's not FreeMarker), but I guess you simily shouldn't initialize count to 0 unless it's yet undefined. That is, instead of that two #assign-s you could write <#assign count = (count!0) + 1>. Of course it matters what the life-cycle of the FreeMarker Environment looks like, as the value of count will be lost if you start a new Environment (like call Template.process).
I'm using NetSuite too and ran into a somewhat similar problem. I don't think your problem is linked to Freemarker, but to Big Faceless Organization (BFO). Freemarker prepares the xml and BFO converts it into a PDF.
More information on BFO can be found here: http://bfo.com/products/report/. That's where you have the concept of header / footer / macros.
Read section "Pagination with tables - headers and footers" from page 35 of the User Guide which describes how to reprint a standard header or footer row in the table.
The table has to be top-level to work (i.e. not within another table.)
I don't yet know the answer to your question, but I can tell you that it may be found in the Big Faceless PDF Library user guide, not Freemarker...
http://bfo.com/products/report/docs/userguide.pdf
The answer relates to the application of special macros:
To display headers and footers on the page, the Report Generator introduces the concept of a “macro” - a block of XML which can be
repeated multiple times throughout the document.
There are three different types of macro attribute, which can be used either on the BODY or PBR elemnts to set a macro for every
page, or for a specific page by using a #pagen entry in a stylesheet.
header > to set the header of the page
footer > to set the footer of the page
background-macro > to set the background of the page
A macro is defined in the HEAD of the document inside a MACROLIST. Each macro must have an ID, which is how it’s referenced later in the document. Here’s an example which sets a standard footer on each page:
<pdf>
<head>
<macrolist>
<macro id="myfooter">
<p align="center">
Page <pagenumber/> of <totalpages/>
</p>
</macro>
</macrolist>
</head>
<body footer="myfooter" footer-height="20mm">
Document contents here
</body>
</pdf>
The “footer” attribute is the ID of the macro, and the “footer-height” attribute is the height required for the footer. If the document
contents require several pages, the footer will be placed on each one, unless there is a PBR element which changes the footer (or
removes it by setting footer="none"). The “header” attribute can be used the same way to set a header at the top of each page.
I know this answer is coming late for the question, but as I was trying to figure out the same thing I learned the answer from Russ's answer and the BFO documentation. Hopefully this will help anyone else out that is looking for the same information. Using the style attribute and the #pagen id you can set a header or footer to a specific page. nlfooter is the name of the footer macro. I am applying this footer to the first page only. Here is the code I used to apply a footer to the first page only.
<style type="text/css">
#page1 {
footer: nlfooter;
footer-height: 10%;
}
</style>
The comment from Russ with the quote from BFO's documentation helped me realize this. Here is the quote with emphasis added.
There are three different types of macro attribute, which can be used either on the BODY or PBR elemnts to set a macro for every page, or for a specific page by using a #pagen entry in a stylesheet.

how to scroll a web application in watir

How do I scroll a web application in Watir ?
I have tried#browser.send_keys :space
This just brings the whole page down. But I have a scroll within the application, I need to scroll the vertical scroll bar down & up in my automation testing, Please help me !
Thanks!
<div dojoattachpoint="containerNode" class="containerNode tabContentPane typeNavigationSingleChild" style="overflow: auto; left: 5px; top: 10px; width: 1549px; height: 535px;">
<div pageid="lifecycle_theme_home_page_dashboard_pageId" id="lifecycle_theme_home_page_dashboard_pageId" style="height: 535px; padding: 0px; width: 1549px;" widgetid="lifecycle_theme_home_page_dashboard_pageId" title="" role="group" class="dijitContentPane wcs-nullLayout">
Solution 1) Scroll to Last Element
I think Vinay's approach should work. However, in the current form, it assumes that the element already exists on the page. I am guessing the element you want is only visible once you scroll far enough. So what you can do is scroll to the last element in the div.
Watir-Webdriver
In Watir-Webdriver:
div_with_scroll = browser.div(:class => 'containerNode tabContentPane typeNavigationSingleChild')
div_with_scroll.elements.last.wd.location_once_scrolled_into_view
Watir-Classic
In Watir-Classic, it is different since it does not use selenium-webdriver:
div_with_scroll = browser.div(:class => 'containerNode tabContentPane typeNavigationSingleChild')
div_with_scroll.elements.last.document.scrollIntoView
Solution 2) Use ScrollTop Property
As an alternative, if the above does not work, you can set the scrollTop property to move the div element's scrollbar. This worked for an application that I was working on that had content that was only loaded once you scrolled to the bottom.
Watir-Webdriver
To jump the scrollbar to the bottom, which in theory should trigger the below content to load, set the scrollTop property to the scrollHeight:
div_with_scroll = browser.div(:class => 'containerNode tabContentPane typeNavigationSingleChild')
scroll_bottom_script = 'arguments[0].scrollTop = arguments[0].scrollHeight'
div_with_scroll.browser.execute_script(scroll_bottom_script, div_with_scroll)
To jump back to the top, set the scrollTop to zero.
div_with_scroll = browser.div(:class => 'containerNode tabContentPane typeNavigationSingleChild')
scroll_top_script = 'arguments[0].scrollTop = 0'
div_with_scroll.browser.execute_script(scroll_top_script, div_with_scroll)
You can also use any value in between depending on where you need to go to.
Watir-Classic
In Watir-Classic, you can set the scrollHeight more directly:
div_with_scroll = browser.div(:class => 'containerNode tabContentPane typeNavigationSingleChild')
#Go to bottom
div_with_scroll.document.scrollTop = div_with_scroll.document.scrollHeight
#Go to top
div_with_scroll.document.scrollTop = 0
if the element is at the bottom of the page, it will load more content:
browser.element.wd.location_once_scrolled_into_view
Using Watir-Classic, the second method Justin Ko provided works great for iterating through a scrollable section to find something specific. Here's an example of that:
div_with_scroll = browser.div(:class => 'containerNode tabContentPane typeNavigationSingleChild')
scroll_value = 50 # change this number to match how much you want to scroll each iteration
max_loop = div_with_scroll.document.scrollHeight / scroll_value
if div_with_scroll.document.scrollHeight % scroll_value > 0 # accounts for any remainder height
max_loop = max_loop + 1
end
for i in 0..max_loop do
div_with_scroll.document.scrollTop = i * scroll_value # moves the scrollbar
if div_with_scroll.text.include? 'Search Text'
puts 'Search Text found in iteration: ' + i.to_s()
break # exits the loop when found
end
end
There may be a more efficient way to do what I'm doing here, but you get the idea.
Use Javascript (eg. bottom of page):
browser.execute_script("window.scrollTo(0, document.body.scrollHeight);\n")
use a correct javascript executor to achieve this result - below i have written some code to show you the 'in my opinion' best and most reliable way to achieve this:
BOTTOM OF PAGE:
((IJavaScriptExecutor)webapplication).ExecuteScript("window.scrollTo(0, document.body.scrollHeight - 5)");
TOP OF PAGE:
((IJavaScriptExecutor)webapplication).ExecuteScript("window.scrollTo(0, document.body.scrollHeight 0)");
you can also set different values to scroll to different heights - for example the scroll to bottom code i have set to 5px from the bottom of the page. good luck, hope this is of somewhat use to you.

My WebPages not consistent with Firefox and Chrome

I have made a website.It worked all fine during the whole development and testing phase of over 20 days during which I viewed the pages always in firefox and they were all fine.But today suddenly I encountered a problem with firefox. The table data are not centered and the borders are not rounded as they used to be earlier.But they are all fine in Google Chrome..You can view the screenshots :
Mozilla Firefox (It not used to be like this !)
Google Chrome
Please tell me how to fix it..I have cleared all the cache and session of firefox but still its the same
UPD
Ok so I am providing the codes as well:
The Php code (only snippet) of the table
$result = mysql_query("SELECT username,rating,contests,rank from users order by (rating) desc limit 10");
echo '<table id="problems">
<thead><tr>
<th colspan="3" align="center" ><font color="red" ><h2>Top Rated</h2></font></th>
</tr></thead>
<tr>
<th>#</th>
<th>Username</th>
<th >Rating </th>
</tr>';
while($row = mysql_fetch_array($result))
{
require_once("color_gen.php");
require_once("rankings.php");
ranker_rater();
$color=ColorGen($row['rating'],$row['contests']);
$uname=$row['username'];
$rank=$row['rank'];
echo "<tr>";
echo "<td>" . $rank. "</td>";
echo '<td><font color="'.$color.'">'.$uname.'</font></td>';
echo "<td>" . $row['rating'] . "</td>";
echo "</tr>";
}
echo "</table>";
And the corresponding CSS
#problems
{
text-align:centre;
border:solid;
border-width:2px;
border-color:#CCC;
width : 100%;
}
#problems th,td
{
padding: 4px;
font-weight: normal;
border:solid;
border-width:1px;
border-color:#CCC;
font-size: 15px;
color: #039;
//background: #b9c9fe;
text-align:center;
}
Know that different browsers have different default functions. This is the fundamental manner in which I attack this problem. Google chrome typically is more kind to web developers and is better at correcting errors. But, if you want something to be consistent throughout all browsers, ensure that the values are stated explicitly.
Problem 1 - Text not centered: I notice that in your CSS, your first line assigns text-align to "centre." The internet was founded by Americans, and all browsers will support the American spelling of "center." The problem is probably that Firefox does not support the British spelling of the word. I won't know until its tried, though.
Problem 2 - Corners not rounded: Since I am not a very skilled web developer, this is a problem I do not know how to solve. However, I've found a blog post by someone who does.

How to press/click the button using Selenium if the button does not have the Id?

I have 2 buttons Cancel and Next button on the same page but it has only one id (see the below code). I wanted to press Next but every time it is identifying the cancel button only not Next button. How to resolve this issue?
<td align="center">
<input type="button" id="cancelButton" value="Cancel" title="cancel" class="Submit_Button" style="background-color: rgb(0, 0, 160);">
<input type="submit" value="Next" title="next" class="Submit_Button">
</td>
Use xpath selector (here's quick tutorial) instead of id:
#python:
from selenium.webdriver import Firefox
YOUR_PAGE_URL = 'http://mypage.com/'
NEXT_BUTTON_XPATH = '//input[#type="submit" and #title="next"]'
browser = Firefox()
browser.get(YOUR_PAGE_URL)
button = browser.find_element_by_xpath(NEXT_BUTTON_XPATH)
button.click()
Or, if you use "vanilla" Selenium, just use same xpath selector instead of button id:
NEXT_BUTTON_XPATH = '//input[#type="submit" and #title="next"]'
selenium.click(NEXT_BUTTON_XPATH)
In Selenium IDE you can do:
Command | clickAndWait
Target | //input[#value='Next' and #title='next']
It should work fine.
use the text and value attributes instead of the id
driver.findElementByXpath("//input[#value='cancel'][#title='cancel']").click();
similarly for Next.
For Next button you can use xpath or cssSelector as below:
xpath for Next button: //input[#value='Next']
cssPath for Next button: input[value=Next]
You don't need to use only identifier as elements locators. You can use a few ways to find an element. Read this article and choose the best for you.
You can use xpath for for identifying that element.
You can achieve this by using cssSelector
// Use of List web elements:
String cssSelectorOfLoginButton="input[type='button'][id='login']";
//****Add cssSelector of your 1st webelement
//List<WebElement> button
=driver.findElements(By.cssSelector(cssSelectorOfLoginButton));
button.get(0).click();
I hope this work for you

Resources