I'm trying to send some text to the search textarea at Google Adwords Keyplanner tool using Selenium python.
When inputting manually the text from textarea goes to its attribute 'title'.
The textarea looks like this:
<textarea class="spl-a sprb-c spl-d" rows="1" id="gwt-debug-keywords-text-area" aria-labelledby="gwt-uid-94 gwt-uid-74" wrap="off" style="overflow: hidden;" dir="ltr" title="mytext"></textarea>
As a result:
driver.find_element_by_tag_name('textarea').send_keys('mytext')
or
driver.find_element_by_id('gwt-debug-keywords-text-area').send_keys('mytext')
produces
selenium.common.exceptions.ElementNotVisibleException: Message: element not visible
Is there another way to send keys to this search textarea? I have like 500 keywords which I need to grab data for.
full code of text area:
<div class="spl-c spI-d" style="width: 575px;">
<div id="gwt-uid-119" class="sprb-a">
<div class="sprb-b spl-b" style="display: none;" aria-hidden="true">For example, flowers or used cars</div>
<textarea id="gwt-debug-keywords-text-area" class="spl-a sprb-c spl-d" rows="1" aria-labelledby="gwt-uid-139 gwt-uid-119" style="overflow: hidden;" dir="ltr" title="my keyword" wrap="off"></textarea>
</div>
</div>
</div>
The element you are trying to interact with is but addressable by Selenium, because it is inside a div which is hidden - this one:
<div class="sprb-b spl-b" style="display: none;" ...
There is another element which is actually taking the user's input - look for elements with keypress event handlers, and also what changes in DOM web you enter characters.
Related
I would like to navigate through a website, find an element and print it.
Python version: 3.10; Selenium Webdriver: Firefox; IDE: PyCharm 2021.3.2 (CE);
OS: Fedora 35 VM
I am able to navigate to the appropriate page where the text is generated in a drop down menu.
When I locate the element by CSS Selector and attempt to print it, the output does print the text "None".
I would like it to print the Plan Name which in this case is "Dual Complete Plan 1".
The element is not always present so I also need to catch any exceptions.
The relevant HTML code of the element I am trying to print:
<span class="OSFillParent" data-expression="" style="font-size: 12px; margin-top: 5px;">Dual Complete Plan 1</span>
More of the HTML code of the element I am trying to print (element I am trying to capture is below the fourth div):
<td data-header="Plan Name">
<div id="b8-b40-l1_0-132_0-$b2" class="OSBlockWidget" data-block="Content.AccordionItem">
<div id="b8-b40-l1_0-132_0-b2-SectionItem" class="section-expandable open is--open small-accordion" data-container="" data-expanded="true" aria-expanded="true" aria-disabled="false" role="tab">
<div id="b8-b40-l1_0-132_0-b2-TitleWrapper" class="section-expandable-title" data-container="" style="cursor: pointer;" role+"button" aria-hidden="false" aria-expanmded="true" tabindex="0" aria-controls="b8-b40-l1_0-132_0-b2-Content" EVENT FLEX
<div id="b8-b40-l1_0-132_0-b2-Title" class="dividers full-width">
<span class="OSFillParent" data-expression="" style="font-size: 12px; margin-top: 5px;">Dual Complete Plan 1</span>
</div>
<div class="section-expandable-icon" data-container="" aria-hidden="true"
::after
</div>
</div>
<div id="b8-b40-l1_0-132_0-b2-ContentWrapper" class="section-expandable-content no-padding is--expanded" data-container="" tabindex="0" aria-hidden="false" aria-labelledby="b8-b40-l1_0-132_0-b2-TitleWrapper">
<div id="b8-b40-l1_0-132_0-b2-Content" role="tabpanel">
<a data-link="" href="https://www.communityplan.com" target="_blank" title="Click for more information"> EVENT
<span class="OSFillParent" data-expression="" style="font-size: 12px;">www.CommunityPlan.com</span>
</a>
<span class="OSFillParent" data-expression="" style="font-size: 12px:">Phone Number: 8005224700</span>
</div>
</div>
</div>
</div>
</td>
My relevant Selenium code:
# Find the Plan Name & if present set it to the variable "Advantage"
try:
Advantage = (WebDriverWait(driver, 5).until(
EC.presence_of_element_located((By.CSS_SELECTOR, "#b8-b40-l1_0-132_0-b2-Title > span:nth-child(1)"))).get_attribute("value"))
except:
pass
print('\033[91;46m', Advantage, '\033[0m')
I expect the output to be "Dual Complete Plan 1", which is what I see on the screen and in the HTML. Instead I get the following:
None
Apparently the "Advantage" variable is being set to "None".
Why?
I can see the text "Dual Complete Plan 1" that I want to print in the HTML code above.
What am I doing wrong?
I feel like I need a primer on "get attribute"?
To get the text Dual Complete Plan 1 you need to use
element.text
or
element.get_attribute("innerHTML")
or
element.get_attribute("textContent")
Instead of presence_of_element_located() use visibility_of_element_located()
and following css selector to identify
div[id*='Title'] > span.OSFillParent
Or
div.dividers.full-width > span.OSFillParent
Code:
try:
Advantage = WebDriverWait(driver, 5).until(
EC.visibility_of_element_located((By.CSS_SELECTOR, "div[id*='Title'] > span.OSFillParent"))).text
except:
pass
print(Advantage )
I am trying to locate and click an element by text. The reason is that the id and location of the element are dynamic but the text is always the same.
Here it is how look like as a HTML:
<div class="p-r" input-title="I want to identify by text here">
<!---->
<div class="skDeleteBtn skRequired">
<input class="input radio--big ng-untouched ng-pristine ng-valid" data-cname="radibutton" type="radio" id="z1jcfqy9">
<label class="label label--radio-big" for="z1jcfqy9" style="color: inherit;">
<span></span>I want to identify by text here
<i class="d-ib va-m ml-3">
<sk-tooltip><!---->
</sk-tooltip>
</i>
</label>
</div>
</div>
I want to identify by text I want to identify by text here.
I want to mention that the location of the text where starts with <span></span> is a little bit weird. Specifically, i think that the text has whitespace and endline after the text, so I prefer to locate and click with input-title="I want to identify by text here">.
So far I tried:
driver.find_element_by_xpath("//*[contains(text(),'{}')]".format('I want to identify by text here'))
driver.find_element_by_xpath("//*[contains(text(),'I want to identify by text here')]")
but no luck.
Thanks in advance!
You just want to identify and click the input-title element? This should work, by text
driver.find_element_by_css_selector('div[input-title="I want to identify by text here"]').click()
F1, need some help or hints with Hidden element using Robotframework.
The problem consist that to fill any text in the text area, I need to change the state of text area from display:none; to display:block;
Needed text area for input
Code that I see from WebDev Tool
The code itself:
<div class="col-md-12">
<div class="cazary" style="width: 664px;">
<div class="cazary-commands-wrapper">
<ul class="cazary-commands-list">
<li unselectable="on" title="Size" class="cazary-command-fontsize">Size</li>
</ul>
<ul class="cazary-commands-list">
<li unselectable="on" title="Foreground Color" class="cazary-command-forecolor">Foreground Color</li>
</ul>
<ul class="cazary-commands-list">
<li unselectable="on" title="Background Color" class="cazary-command-backcolor">Background Color</li>
</ul>
<ul class="cazary-commands-list">
<li unselectable="on" title="Remove Format" class="cazary-command-removeformat">Remove Format</li>
</ul>
</div>
<iframe class="cazary-edit" src="javascript:" style="height: 39px;"></iframe>
<textarea id="summernote" class="required-preview field cazary-source" placeholder="Tell us all about your Advertisement. This description will be prominently displayed in your Advertisement notice. Feel free to adjust the fonts and background colour too." name="observations" cols="50" rows="10" style="display: none;"></textarea>
</div>
My Robotframework code tries:
Select Frame //iframe[#class="cazary-edit"]
# First try
Input text //textarea[#id="summernote"] ${UniversalVariableforName}
# Second try
Input text //iframe[#class="cazary-edit"] ${UniversalVariableforName}
# Third try
Input text //div[#class="cazary"]//iframe[#class="cazary-edit"] ${UniversalVariableforName}
# Fourth try
Input text //body[#class="empty"] ${UniversalVariableforName}
# Fifth try
Input text //iframe[#class="cazary-edit"]//body[#class="empty"] ${UniversalVariableforName}
Errors that were returned:
image
May be there is a solution with Execute Javascript keyword?
The concerned <textarea> is outside of the <iframe class="cazary-edit">. Hence we don't need to switch to the <iframe>
To send the text to the Input field you can try to :
Use xpath as :
"//textarea[#class='required-preview field cazary-source' and #id='summernote']"
Click the Input field first.
Next Clear the Input field.
Finally try to send the text.
Update :
As the concerned textarea have the style attribute set as "display: none;", we have to change to "display: block;" through JavascriptExecutor then send the text.
Python Sample Code :
driver.execute_script("document.getElementById('ID').style.display='block';")
<div id="crmMasthead" tabindex="-1">
<div id="crmTopBar" class="ms-crm-TopBarContainer ms-crm-TopBarContainerGlobal newNavBarMode">
<div id="crmAppMessageBar" class="crmAppMessageBar" style="display: none; height: 0px;">
<div id="crmRibbonManager" currentribbonelement="commandContainer15" style="height: 62px; display: block; visibility: visible;">
<div id="commandContainer15" style="display: inline;">
<ul class="ms-crm-CommandBar-Menu" role="application">
<li id="ewrb_importfile|NoRelationship|HomePageGrid|Mscrm.HomepageGrid.ewrb_importfile.NewRecord" class="ms-crm-CommandBarItem ms-crm-CommandBar-Menu ms-crm-CommandBar-Button" tabindex="-1" title="New Create a new Import File record." command="ewrb_importfile|NoRelationship|HomePageGrid|Mscrm.NewRecordFromGrid" style="white-space: pre-line; display: inline-block;">
<span class="ms-crm-CommandBar-Button ms-crm-Menu-Label-Hovered" tabindex="-1" style="max-width:200px">
<a class="ms-crm-Menu-Label" tabindex="0" onclick="return false">
<img class="ms-crm-ImageStrip-New_16 ms-crm-commandbar-image16by16" tabindex="-1" src="/_imgs/imagestrips/transparent_spacer.gif" style="vertical-align:top"/>
<span class="ms-crm-CommandBar-Menu" tabindex="-1" style="max-width:150px" command="ewrb_importfile|NoRelationship|HomePageGrid|Mscrm.NewRecordFromGrid"> New </span>
<div class="ms-crm-div-NotVisible"> Create a new Import File record. </div>
</a>
</span>
</li>
The Xpath Shows me like this:
.//*[#id='ewrb_importfile|NoRelationship|HomePageGrid|Mscrm.HomepageGrid.ewrb_importfile.NewRecord']/span/a
and If i use this, Selenium doesn't click the button
First try to remove "."(dot) from your xpath and check it if it works.
Secondly, try to write the xpath yourself. For this a node, try this one:
//a[#class="ms-crm-Menu-Label"]
You should check it if the part of html that you share is inside an iframe node or not. Otherwise, you should share more. With the current part that you shared, it is not possible to say that if it is inside an iframe or not.
Also, it can be a good idea to check the visibility of the button. The last thing: do you receive any error message. If yes, share it.
As part of automation testing, I'm trying to figure out what is the best way to access a multi-select button in my company website. This button is not design in the popular way and it causes me problems using Select library. Here is how it looks like:
<div class="select-options options-overflow drop-select-link" style="position: absolute; top: 373px; left: 492px; width: 53px;">
<div class="drop-holder">
<div class="drop-list" style="height: 100px; overflow-x: hidden; overflow-y: auto;">
<ul>
<li class="jcfcalc" rel="0">
<a href="#">
<span>USD</span>
</a>
</li>
<li class="option-even jcfcalc" rel="1">
<a href="#">
<span>EUR</span>
</a>
</li>
</ul>
</div>
</div>
</div>
What you see here is a multi-select button which displayed different kind of currencies. I want to be able to choose currencies in a wise way - something like Select library. However, Select library doesn't fit to my code.
Is there a library that I'm not aware of? or would I have to do it with XPaths?
Select() couldn't be used with buttons. Any buttons! It could be used with select/option elements only!
In your case you can simply use link text to select required element (which is link, not the button) as
driver.find_element_by_link_text("EUR")
driver.find_element_by_link_text("USD")