I am trying to interact with an external website at: http://is.gd/LtgYEk
I need to be able to fill in the input with id="textOrigen" here is the html
<p>
<label class="form-label">Departing from:</label>
<span class="label-field">
<input type="text" autocomplete="off" onblur="onblur2('textOrigen');" onfocus="initID('textOrigen');" size="17" id="textOrigen" name="text" maxlength="40" style="position:static;color: #505050;">
<select style="display:none" onchange="clearValidate(); Origen();" class="validate[dynamic]" id="cmbOrigen" name="cmbOrigen">
<option value="-1" selected="selected">Origin</option>
</select>
<label class="label-error" id="lblerrorOrigen"></label>
</span>
</p>
I put together a simple ruby script using 'capybara/poltergeist'
I am unable to replicate the browser behavior, which is:
on click the input field default value is highlighted thus being deleted as you start typing.
I lost track of all different variations I tried, but tried many. I found another SO post which seemed somewhat useful but it didn't help
This is the last revision of the method to fill this field:
def session.fill_autocomplete(field, options = {})
execute_script %Q{ $('##{field}').trigger('focus') }
fill_in field, with: options[:with]
execute_script %Q{ $('##{field}').trigger('focus') }
execute_script %Q{ $('##{field}').trigger('keydown') }
selector = %Q{#output div:contains('#{options[:with]}')}
execute_script "$(\"#{selector}\").mouseenter().click()"
end
As I wrote the script is very simple, the only other relevant bit is when the session is instantiated with:
session = Capybara::Session.new(:poltergeist)
Any help would be greatly appreciated.
I noticed that using the right version of phantomjs is fundamental.
Although 2.x is out, I noticed that phantomjs 1.8.2 behaves much more as expected and is way less buggy.
I'm currently testing autocompleted fields in RailsAdmin with success without using any delay technique.
def fill_in_autocomplete(selector, text)
find(selector).native.send_keys(*text.chars)
end
def choose_autocomplete_entry(text)
find('ul.ui-autocomplete').should have_content(text)
page.execute_script("$('.ui-menu-item:contains(\"#{text}\")').find('a').trigger('mouseenter').click()")
end
An example selector for fill_in_autocomplete would be:
".author_field .ui-autocomplete-input"
I found the solution after testing in many ways.
The key was to add some delay to allow the auto suggest div to be populated.
Here is the method that worked:
def session.fill_city(field, options = {})
sleep 3
script = %Q{ $("#{field}").focus().keypress().val("#{options[:with]}") }
execute_script(script)
sleep 2
find('#output').find('div').trigger('click')
end
Related
I want the text "HEATMAPS" to be clicked after the webpage is opened. I have tried number of click methods, including recognizing as hyperlink, as text, as using xpath etc. None of them worked. I feel, I am either misunderstanding the links, as to be a hyperlink or choosing a wrong xpath.
Link of the web page
PFB the code below
require 'watir-webdriver'
require 'watir-ng'
WatirNg.patch!
WatirNg.register(:ng_scope).patch!
browser = Watir::Browser.new
browser.goto 'http://app.vwo.com/#/campaign/108/summary? token=eyJhY2NvdW50X2lkIjoxNTA3MzQsImV4cGVyaW1lbnRfaWQiOjEwOCwiY3JlYXRlZF9vbiI6MTQ0NDgxMjQ4MSwidHlwZSI6ImNhbXBhaWduIiwidmVyc2lvbiI6MSwiaGFzaCI6IjJmZjk3OTVjZTgwNmFmZjJiOTI5NDczMTc5YTBlODQxIn0='
lin = browser.link :text=> 'HEATMAPS'
lin.exist?
lin.click
Can someone please guide me on this, as to how I can make that link with the text "HEATMAPS" in the page get clicked.
The error i get:
`This code has slept for the duration of the default timeout waiting for an Element to exist. If the test is still passing, consider using Element#exists? instead of rescuing UnknownObjectException
C:/Ruby22/lib/ruby/gems/2.2.0/gems/watir-6.1.0/lib/watir/elements/element.rb:507:in `rescue in wait_for_exists': timed out after 30 seconds, waiting for {:text=>"HEATMAPS", :tag_name=>"a"} to be located (Watir::Exception::UnknownObjectException)
from C:/Ruby22/lib/ruby/gems/2.2.0/gems/watir-6.1.0/lib/watir/elements/element.rb:497:in `wait_for_exists'
from C:/Ruby22/lib/ruby/gems/2.2.0/gems/watir-6.1.0/lib/watir/elements/element.rb:515:in `wait_for_present'
from C:/Ruby22/lib/ruby/gems/2.2.0/gems/watir-6.1.0/lib/watir/elements/element.rb:533:in `wait_for_enabled'
from C:/Ruby22/lib/ruby/gems/2.2.0/gems/watir-6.1.0/lib/watir/elements/element.rb:656:in `element_call'
from C:/Ruby22/lib/ruby/gems/2.2.0/gems/watir-6.1.0/lib/watir/elements/element.rb:114:in `click'
from C:/Users/Mrityunjeyan/Documents/GitHub/Simpleprograms/webautomation.rb:10:in `<main>'`
This would display me the inner_html text but still wouldnt click
lin = browser.span(:class => 'ng-scope').inner_html
puts lin
The problem is that the link's text is not "HEATMAPS". It is actually "Heatmaps". The text locator is case-sensitive, which means you need:
lin = browser.link :text=> 'Heatmaps'
You can see this if you inspect the HTML:
<a ui-sref="campaign.heatmap-clickmap" href="#/analyze/analysis/108/heatmaps?token=eyJhY2NvdW50X2lkIjoxNTA3MzQsImV4cGVyaW1lbnRfaWQiOjEwOCwiY3JlYXRlZF9vbiI6MTQ0NDgxMjQ4MSwidHlwZSI6ImNhbXBhaWduIiwidmVyc2lvbiI6MSwiaGFzaCI6IjJmZjk3OTVjZTgwNmFmZjJiOTI5NDczMTc5YTBlODQxIn0%3D">
<!-- boIf: isAnalyticsCampaign -->
<span bo-if="isAnalyticsCampaign" class="ng-scope">Heatmaps</span>
<!-- boIf: !isAnalyticsCampaign -->
</a>
It only looks like "HEATMAPS" due to the styling. One of the styles includes a text-transform: uppercase; which visually capitalizes the text. Watir does not interpret the styles, so only knows that the text node is "Heatmaps".
Once you have identified the link, clicking still has a problem:
lin.click
#=> Selenium::WebDriver::Error::UnknownError:
#=> unknown error: Element <a ui-sref="analyze.heatmaps" ng-class="{selected: (locationContains('analyze', 'heatmap') && !locationContains('analyze', '/analysis') && state.current.name !== 'campaign.heatmap-clickmap') || (isAnalyzeHeatmapEnabled && (isAnalyzeDeprecatedHeatmapView || locationContains('analyze', '/analysis', 'heatmaps')) )}" data-qa="nav-main-analyze-heatmap" href="#/analyze/heatmap">...</a>
#=> is not clickable at point (90, 121).
#=> Other element would receive the click: <div ng-show="!isCROSetupView" class="">...</div>
The link being located is actually the one in the left menu, which is disabled, rather than the top menu. You need to scope the link locator to just the top menu. Using the parent ul element appears to be sufficient:
lin = browser.ul(class: 'page-nav').link(text: 'Heatmaps')
lin.click
To see the click complete, you might want to tell Chrome not to close at the end of the script. This is done by opening the browser using the following option:
caps = Selenium::WebDriver::Remote::Capabilities.chrome("chromeOptions" => {'detach' => true})
browser = Watir::Browser.new :chrome, desired_capabilities: caps
Your target link doesn't have any text. I confirmed with nokogiri that the text of the <a> tag includes the text inside the child <span> tag, and it turns out Watir works the same way.
If you use a Chrome browser, you can select:
View > Developer > Developer tools
Then you can select an element on the page, and the corresponding section in the html will be highlighted. Here is what the html looks like:
<a ui-sref="campaign.heatmap-clickmap"
href="#/analyze/analysis/108/heatmaps?token=eyJhY2NvdW50X2lkIjoxNTA3MzQsImV4cGVyaW1lbnRfaWQiOjEwOCwiY3JlYXRlZF9vbiI6MTQ0NDgxMjQ4MSwidHlwZSI6ImNhbXBhaWduIiwidmVyc2lvbiI6MSwiaGFzaCI6IjJmZjk3OTVjZTgwNmFmZjJiOTI5NDczMTc5YTBlODQxIn0%3D">
<!-- boIf: isAnalyticsCampaign -->
<span bo-if="isAnalyticsCampaign" class="ng-scope">Heatmaps</span>
<!-- boIf: !isAnalyticsCampaign --> </a>
The basic structure is:
<a><span>Heatmaps</span></a>
Chrome even has a feature where you can right click on an element and get its xpath, which you can use with Watir.
However, when I execute my program to go to that page, I see Chrome launch, and then I'm presented with a login page rather than the page that was presented to me at your link.
Arghhh...what a colossal waste of time. I thought Watir must be broken. With the proper url, I can get the link using several different techniques:
1)
require 'watir'
require 'watir-ng' #<=NOTE THIS
WatirNg.register(:'bo_if').patch! #<= NOTE THIS
br = Watir::Browser.new :chrome
br.goto 'http://app.vwo.com/#/analyze/analysis/108/summary?token=eyJhY2NvdW50X2lkIjoxNTA3MzQsImV4cGVyaW1lbnRfaWQiOjEwOCwiY3JlYXRlZF9vbiI6MTQ0NDgxMjQ4MSwidHlwZSI6ImNhbXBhaWduIiwidmVyc2lvbiI6MSwiaGFzaCI6IjJmZjk3OTVjZTgwNmFmZjJiOTI5NDczMTc5YTBlODQxIn0%3D'
target_link = br.span(
class: 'ng-scope',
'bo_if': 'isAnalyticsCampaign',
).parent #<= NOTE THIS
puts target_link.text #HEATMAPS
puts target_link.href #http://app.vwo.com/#/analyze/analysis/1.....
2)
require 'watir'
require 'watir-ng' #<=NOTE THIS
WatirNg.register(:ui_sref).patch! #<=NOTE THIS
br = Watir::Browser.new :chrome
br.goto 'http://app.vwo.com/#/analyze/analysis/108/summary?token=eyJhY2NvdW50X2lkIjoxNTA3MzQsImV4cGVyaW1lbnRfaWQiOjEwOCwiY3JlYXRlZF9vbiI6MTQ0NDgxMjQ4MSwidHlwZSI6ImNhbXBhaWduIiwidmVyc2lvbiI6MSwiaGFzaCI6IjJmZjk3OTVjZTgwNmFmZjJiOTI5NDczMTc5YTBlODQxIn0%3D'
target_link = br.link(
ui_sref: 'campaign.heatmap-clickmap',
href: '#/analyze/analysis/108/heatmaps?token=eyJhY2NvdW50X2lkIjoxNTA3MzQsImV4cGVyaW1lbnRfaWQiOjEwOCwiY3JlYXRlZF9vbiI6MTQ0NDgxMjQ4MSwidHlwZSI6ImNhbXBhaWduIiwidmVyc2lvbiI6MSwiaGFzaCI6IjJmZjk3OTVjZTgwNmFmZjJiOTI5NDczMTc5YTBlODQxIn0%3D'
)
puts target_link.text #HEATMAPS
puts target_link.href #http://app.vwo.com/#/analyze/analysis/108...
3) Getting the xpath by right clicking on the link in Chrome:
require 'watir'
br = Watir::Browser.new :chrome
br.goto 'http://app.vwo.com/#/analyze/analysis/108/summary?token=eyJhY2NvdW50X2lkIjoxNTA3MzQsImV4cGVyaW1lbnRfaWQiOjEwOCwiY3JlYXRlZF9vbiI6MTQ0NDgxMjQ4MSwidHlwZSI6ImNhbXBhaWduIiwidmVyc2lvbiI6MSwiaGFzaCI6IjJmZjk3OTVjZTgwNmFmZjJiOTI5NDczMTc5YTBlODQxIn0%3D'
target_link = br.link(
xpath: '//*[#id="main-container"]/ul/li[3]/a'
)
puts target_link.text #HEATMAPS
puts target_link.href #http://app.vwo.com/#/analyze/analysis/108....
xpath can handle any tag or attribute name, unlike Watir, so it seems like a good tool in that regard.
4) A less brittle xpath:
require 'watir'
br = Watir::Browser.new :chrome
br.goto 'http://app.vwo.com/#/analyze/analysis/108/summary?token=eyJhY2NvdW50X2lkIjoxNTA3MzQsImV4cGVyaW1lbnRfaWQiOjEwOCwiY3JlYXRlZF9vbiI6MTQ0NDgxMjQ4MSwidHlwZSI6ImNhbXBhaWduIiwidmVyc2lvbiI6MSwiaGFzaCI6IjJmZjk3OTVjZTgwNmFmZjJiOTI5NDczMTc5YTBlODQxIn0%3D'
a_href = "#/analyze/analysis/108/heatmaps?token=eyJhY2NvdW50X2lkIjoxNTA3MzQsImV4cGVyaW1lbnRfaWQiOjEwOCwiY3JlYXRlZF9vbiI6MTQ0NDgxMjQ4MSwidHlwZSI6ImNhbXBhaWduIiwidmVyc2lvbiI6MSwiaGFzaCI6IjJmZjk3OTVjZTgwNmFmZjJiOTI5NDczMTc5YTBlODQxIn0%3D"
target_link = br.link(
xpath: %Q{ //a[#href="#{a_href}"] } +
'[#ui-sref="campaign.heatmap-clickmap"]' +
'[child::span[#class="ng-scope"][#bo-if="isAnalyticsCampaign"][text()="Heatmaps"]]'
)
The xpath looks for an <a> tag with two attributes:
//a[#href="blah"][#ui-sref="bleh"]
which has a child <span> (i.e. a direct child) with three attributes:
[child::span[#class="blih"][#bo-if="bloh"][text()="Heatmaps"]]
After I programmatically click the link:
target_link.click
Watir goes to the next page.
Here is source html:
<div id="alert_signin" class="alert_modal_error">
<div class="alert alert-danger alert-dismissable">
<button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button>
Invalid username or password.
</div>
</div>
What I really need is to check if message "Invalid username or password." appears (python + selenium webdriver ). But I was unlucky to find it using xpath like
find_element_by_xpath('//div[#id=\'alert_signin\']/div[#class=\'alert\']').text
So I've decided to find exact xpath using message text. I've tried several options like
find_element_by_xpath('//*[text()[contains(.,\'Invalid\')]]')
or
find_element_by_xpath('//*[contains(., \'Invalid username or password.\')]')
but each time got "NoSuchElementException: Unable to locate element: {"method":"xpath","selector": blablabla"
Please advice
You cannot directly point your expressions to the text nodes in Selenium.
Instead, I would get the entire "alert" text:
alert_text = driver.find_element_by_css_selector("#alert_signin .alert").text
Then, you can either apply the "contains" check:
assert "Invalid username or password." in alert_text
Or, remove the "x" part:
alert_text = alert_text.replace(u"×", "").strip()
assert alert_text == "Invalid username or password."
Examples in Python.
Can you provide some more info, please:
-- Is there a button that you click to get the message?
-- Is the message within a browser-specific alert, or is it a displayed text on the page?
(if the latter is the case, try something like if "Invalid username or password." in driver.page_source: print "SUCCESS!")
actually what I've found is that the only thing I need is using implicitly_wait.
this code works fine:
sign_in.click()
driver.implicitly_wait(30)
alert_text = driver.find_element_by_css_selector("div#alert_signin > div.alert.alert-danger.alert-dismissable").text
alert_text = alert_text.replace(u"×", "").strip()
assert alert_text == "Invalid username or password."
however note from alecxe was very useful while I was trying to verify my approach
You cannot directly point your expressions to the text nodes in Selenium.
I'm trying to write a script that will automatically click a button when entering a site.
The HTML of the site is as follows:
<span id="zolaDisclaimerButton" class="dijitReset dijitStretch dijitButtonContents" waistate="labelledby-zolaDisclaimerButton_label" wairole="button" dojoattachpoint="titleNode,focusNode" role="button" aria-labelledby="zolaDisclaimerButton_label" tabindex="0" title="I acknowledge this disclaimer... Let ZoLa begin!" style="-moz-user-select: none;">
I have tried the following and they don't work:
browser.span(:id, "zolaDisclaimerButton").click
browser.button(:id, "zolaDisclaimerButton").click
How do I go about clicking those types of button? The URL in question is:
http://gis.nyc.gov/doitt/nycitymap/template?applicationName=ZOLA
EDIT: this is the code I use:
require "watir"
browser = Watir::Browser.new
browser.goto "http://gis.nyc.gov/doitt/nycitymap/template?applicationName=ZOLA"
browser.span(:id, "zolaDisclaimerButton").click
puts "fin"
It navigates to the page, doesn't click anything, then prints 'fin' (to let me know it's done). No exception is thrown.
If the page is not loading in time, you can add waits - see http://watirwebdriver.com/waiting/. These wait methods will wait until either the condition is met or a time limit is exceeded. It is better than using sleep since it only waits as long as needed (rather than waiting 2 seconds for something that loads in 1 second).
In this case, use the when_present method on the span before clicking it:
require "watir"
browser = Watir::Browser.new
browser.goto "http://gis.nyc.gov/doitt/nycitymap/template?applicationName=ZOLA"
browser.span(:id, "zolaDisclaimerButton").when_present.click
puts "fin"
I'm new to Ruby and for my first scripting assignment, I've been asked to write a web scraping script to grab elements of our DNS listings from GoDaddy.
Having issues with scraping the links and then I need to follow the links. I need to get the link from the "GoToSecondaryDNS" js element below. I'm using Mechanize and Nokogiri:
<td class="listCellBorder" align="left" style="width:170px;">
<div style="padding-left:4px;">
<div id="gvZones21divDynamicDNS"></div>
<div id="gvZones21divMasterSlave" cicode="41022" onclick="GoToSecondaryDNS('iwanttoscrapethislink.com',0)" class="listFeatureButton secondaryDNSNoPremium" onmouseover="ShowSecondaryDNSAd(this, event);" onmouseout="HideAdInList(event);"></div>
<div id="gvZones21divDNSSec" cicode="41023" class="listFeatureButton DNSSECButtonNoPremium" onmouseover="ShowDNSSecAd(this, event);" onmouseout="HideAdInList(event);" onclick="UpgradeLinkActionByID('gvZones21divDNSSec'); return false;" useClick="true" clickObj="aDNSSecUpgradeClicker"></div>
<div id="gvZones21divVanityNS" onclick="GoToVanityNS('iwanttoscrapethislink.com',0)" class="listFeatureButton vanityNameserversNoPremium" onmouseover="ShowVanityNSAd(this, event);" onmouseout="HideAdInList(event);"></div>
<div style="clear:both;"></div>
</div>
</td>
How can I scrape the link 'iwanttoscrapethislink.com' and then interact with the onclick to follow the link and scrape content on the following page with Ruby?
So far, I have a simple start to the code:
require 'rubygems'
require 'mechanize'
require 'open-uri'
def get_godaddy_data(url)
web_agent = Mechanize.new
result = nil
### login to GoDaddy admin
page = web_agent.get('https://dns.godaddy.com/Default.aspx?sa=')
## there is only one form and it is the first form on thepage
form = page.forms.first
form.username = 'blank'
form.password = 'blank'
## form.submit
web_agent.submit(form, form.buttons.first)
site_name = page.css('div.gvZones21divMasterSlave onclick td')
### export dns zone data
page = web_agent.get('https://dns.godaddy.com/ZoneFile.aspx?zone=' + site_name + '&zoneType=0&refer=dcc')
form = page.forms[3]
web_agent.submit(form, form.buttons.first).save(uri.host + 'scrape.txt')
## end
end
### read export file
##return File.open(uri.host + 'scrape.txt', 'rb') { |file| file.read }
end
def scrape_dns(url)
site_name = page.css('div.gvZones21divMasterSlave onclick td')
LIST_URL = "https://dns.godaddy.com/ZoneFile.aspx?zone=" + site_name + '&zoneType=0&refer=dcc"
page = Nokogiri::HTML(open(LIST_URL))
#not sure how to scrape onclick urls and then how to click through to continue scraping on the second page for each individual DNS
end
You can't interact with "onclick" because Nokogiri isn't a JavaScript engine.
You can extract the contents and then use that as the URL for a subsequent web request. Assuming doc contains the parsed HTML:
doc.at('div[onclick^="GoToSecondaryDNS"]')['onclick']
will give you the value for the onclick parameter. ^= means "find the word starting with", so that lets us rule out other <div> tags with onclick parameters and returns:
"GoToSecondaryDNS('iwanttoscrapethislink.com',0)"
Using a simple regex [/'(.+)'/,1] will get you the hostname:
doc.at('div[onclick^="GoToSecondaryDNS"]')['onclick'][/'(.+)'/,1]
=> "iwanttoscrapethislink.com"
The rest, such as how to get access to Mechanize's internal Nokogiri document, and how to create the new URL, are left for you to figure out.
I've written a program that measures my typing speed. As part of this, I need it to count how many characters I've typed. I did that with
text = gets.chomp
puts text.length.to_s
Unfortunately, I can't get this working for a long string.
In the SciTE editor, .length doesn't work properly, so instead of giving me the length of the string, it gives me the character count of everything I've typed, including corrected mistakes - if I typo "Hrello" and correct it to "Hello", it'll still return 6 instead of 5.
I googled this, and the suggested fix was to run the program from the command prompt instead. In the command prompt, .length works fine, but it turned out that I can't type in more than 264 characters.
So I tried to put a GUI on the program with Shoes:
Shoes.app :width => 300, :height => 300 do
button "Start." do
text = ask "Type here."
para text.length.to_s
end
end
and discovered that Shoes' input box has an even shorter character limit.
I'm running Windows 7, Ruby 1.9.2, SciTe version 2.29 and Shoes Policeman Revision 1514.
How can I run this program so it'll correctly measure the length of a really long string? I'd be happy with any solution that fixes the command prompt or Shoes character limit, the SciTE bug, or just a suggestion for a different way to execute ruby programs where this will work.
I'd be happy with [...] a suggestion for a different way to execute ruby programs where this will work.
What about a simple web app? Here is a simple Sinatra app that accomplishes exactly what you have asked with a very large character limit.
require 'sinatra'
get '/' do
%{<html>
<body>
<form method="post">
<textarea name="typed"></textarea>
<input type="submit">
</form>
</body>
</html>
}
end
post '/' do
"You typed #{params['typed'].length} characters."
end
To run the app you can use something as simple as ruby sinatra_example.rb to use a built-in web server. Or, you can deploy this app using any of several web servers.
If you need timers this should be easy to accomplish through javascript and include in the form submit.
Ok, your question is not accurately titled, but lets see:
There is a very broad number of options of using command prompt, and you should consider running a simple script in ruby on it.
On command line from windows, try typing ruby C:/path_to_folder_program/program.rb
If it won`t execute, you can find on ruby folder some executable called ruby and should, from command prompt on that path, run it like above.
But let me ask you, why ruby? Other more accessible and user-friendly programming languages, like javascript would behave better and would be easier to make your program accessible.
- EDIT -
Seems shoes can handle more chars, use edit_box instead of ask:
In Shoes:
Shoes.app do
#txt = edit_box
button("How many"){ alert(#txt.text.size) }
end
Anyway, before trying shoes I did the exercise with that I knew, here it is:
In javascript:
<script>
function start_stop(){
var txt = document.getElementById('txt');
var btn = document.getElementById('btn');
if( txt.disabled ){
txt.value = '';
txt.disabled = false;
btn.value = 'Stop';
txt.focus();
startTime = new Date().getSeconds();
} else {
txt.disabled = true;
btn.value = 'Start again';
timeNow = new Date().getSeconds();
alert(txt.value.length + " characters in " + (timeNow - startTime) + " seconds.");
}
}
</script>
<input type='button' id='btn' onclick='start_stop()' value='Start'>
<textarea id='txt' rows='8' cols='80' disabled></textarea>
In Ruby using Qt: (replicating the same idea as in the javascript one)
require 'Qt'
class MyWidget < Qt::Widget
slots :start_stop
def initialize
super
setFixedSize(400, 120)
#btn = Qt::PushButton.new("Start")
#txt = Qt::TextEdit.new ; #txt.readOnly = true
vbox = Qt::VBoxLayout.new
vbox.addWidget #btn
vbox.addWidget #txt
setLayout vbox
connect(#btn, SIGNAL("clicked()"), self, SLOT(:start_stop))
end
def start_stop
if #txt.readOnly
#txt.plainText = ''
#txt.readOnly = false
#btn.text = "Stop"
#txt.setFocus
#startTime = Time.now
else
#txt.readOnly = true
#btn.text = "Start again (#{#txt.plainText.size} chars #{(Time.now - #startTime).to_i} in seconds)"
end
end
end
app = Qt::Application.new(ARGV)
widget = MyWidget.new
widget.show
app.exec