Well I'm facing an issue here:
I use Selenium to automate test on my application, and I use the following code to fill a textbox:
driver.find_element_by_id("form_widget_serial_number").send_keys("example", u'\u0009')
All the textboxes have the same id (form_widget_serial_number) so it's impossible to select a specific textbox by using selection by id (the code above selects the first textbox and u'\u0009' changes the cursor position to the next textbox).
Anyway, how can I send values to the "current" textbox without using find_element_by_id or another selector, given that the cursor is in the current textbox?
There are several selectors available to you - Xpath and css in particular are very powerful.
Xpath can even select by the text of an element and then access its second sibling1:
elem = driver.find_element(:xpath, "//div[contains(text(), 'match this text')]/following-sibling::*[2]")
If you need to find the current element that has focus:
focused_elem = driver.switch_to.active_element
And then to find the next one:
elem_sibling = focused_elem.find_element(:xpath, "following-sibling::*")
Using this example, you could easily traverse any sequence of sequential elements, which would appear to solve your problem.
Take a close look at the structure of the page and then see how you would navigate to the element you need from a reference you can get to. There is probably an Xpath or css selector that can make the traversal across the document.
1 FYI, I'm using an old version of Selenium in Ruby, in case your version's syntax is different
My approach would be:
Get a list of all contemplable elements by the known id
Loop over them until you find a focused element
Use send_keys to write into that element
To get the focused element something like
get_element_index('dom=document.activeElement')
might work. See this question for more information.
Edit: If the list you get from 1. is accidently sorted properly the index of an element in this list might even represent the number of u'\u0009' you have to send to reach that specific element.
Use ActionChains utility to do that. Use following code:
from selenium.webdriver.common.action_chains import ActionChains
ActionChains(driver).send_keys("Hello").perform()
Related
I have created a presentation using python-pptx. However, some slides have the empty placeholders with default text click to add title/text that looks like the one below.
So basically, there are non-empty placeholder with text Some texts here and other two are empty placeholders. How can I find and delete them? Also, there are same empty placeholders for images. How can I find them as well. Thanks
Finding them is fairly easy; something roughly like this should do the trick:
for placeholder in slide.shapes.placeholders:
if placeholder.has_text_frame and placeholder.text_frame.text == "":
print("found one %s" % placeholder)
Deleting it is harder, because there is no direct API support for deleting shapes. However, in this simple case of text placeholders, this should work:
sp = placeholder._sp
sp.getparent().remove(sp)
The ._sp attribute is the lxml etree._Element object representing the actual shape XML element (a placeholder <p:sp> element in this case). .getparent() and .remove() are methods on etree._Element and calling these manipulates the underlying XML directly. This can be dangerous, like if you tried this with a chart shape you'd probably get a repair error when you tried to load the presentation, but in this case it's safe enough.
I have a website that was produced in sitecore that i have inherited. The search does not seem to be working correctly. Basically documents do not seem to be returned correctly. I have noted that there is the default sitecore_web_index index and also a custom index that seems to index the same content more or less. Currently the search queries the custom index however I would like to change the query to the default index to see if the document is then returned. I was told you can specify which index to use but the person never told me how to do it. Does anyone know how i can change this?
Sitecore 8 content search uses Sitecore.ContentSearch.ContentSearchManager.GetIndex(...) method to retrieve chosen index.
You can pass either:
Index name as a string:
Sitecore.ContentSearch.ContentSearchManager.GetIndex("sitecore_web_index")
IIndexable item - in this case Sitecore will try to find first registered index for you:
Sitecore.ContentSearch.ContentSearchManager.GetIndex(iIndexable)
Just find where GetIndex is used in your code and replace it with a default index name.
One thing you should be aware of - there is a chance that your custom index has some customization added (like computed fields, list of fields indexed etc). Be careful with any changes. Maybe there are other reasons why your search doesn't work. Try using IndexingManager app to rebuild the indexes and see if it helps.
You also need to remember that on Content Manager environment, the "sitecore_master_index" will be used, and on CD Environment the "sitecore_web_index" will be used
so this can lead to test errors
You can try to get the index dynamically, in that case, the code will select the correct index use, According to their environment
var indexable = Sitecore.Context.Item as SitecoreIndexableItem;
ISearchIndex index = ContentSearchManager.GetIndex(indexable);
using (IProviderSearchContext context = index.CreateSearchContext())
{
//search code...
}
Had to do it this way ...
var indexable = (SitecoreIndexableItem)Sitecore.Context.Item;
I would like to extract certain data from websites.
Originally, I was converting to .txt file and then writing some routines in Python to filter/read out the data, which worked for 95% of the data, which is not sufficient. I found that there is a way with lxml, which I tried, but could not succeed. With XPATH I think I mark the correct position, however, I get only empty brackets as result []. If anybody knew how to correct it, would be highly appreciated.
Thanks.
Peter
from lxml import html
import requests
page=requests.get('http://www.finanzen.net/analyse/ING_Group_NV_overweight-JP_Morgan_Chase__Co__529284')
tree=html.fromstring(page.text)
unternehmen=tree.xpath('/html/body/div[1]/div[8]/div[2]/div[3]/div[4]/div[1]/div/div[2]/div[4]/div[2]/table/tbody/tr[1]/td[1]/br')
#This should fetch the information about unternehmen
print unternehmen
That page source code is a mess. Very little id attributes and many anonymous <div>. You could get the nearest element with an id attribute, go up to its parent, root of the table that keeps the element you want to extract. Following xpath expression worked for me. Give it a try:
response.xpath('//a[#id="commentLink"]/ancestor::div[4]/div[2]/div[4]/div[2]/table/tr/td[1]/text()')[0]
It yields:
u'ING Group NV'
The last [0] is because it's hard to parse non-closed <br> tags and td column retrieves three text elements, so I get only the first one. You will have to adapt it to your needs.
I have a situation where I'm using the IEditorDataFilter interface within a custom UltraGrid editor control to automatically map values from a bound data source when they're displayed in the grid cells. In this case it's converting guid-based key values into user-friendly values, and it works well by displaying what I need in the cell, but retaining the GUID values as the 'value' behind the scenes.
My issue is what happens when I enable the built-in group by functionality and the user groups by a column using my editor. In that case the group by headers default to using the cell's value, which is the guid in my case, so I end up with headers like this:
Column A: 7F720CE8-123A-4A5D-95A7-6DC6EFFE5009 (10 items)
What I really want is the cell's display value to be used instead so it's something like this:
Column A: Item 1 (10 items)
What I've tried so far
Infragistics provides a couple mechanisms for modifying what's shown in group by rows:
GroupByRowDescriptionMask property of the grid (http://bit.ly/1g72t1b)
Manually set the row description via the InitializeGroupByRow event (http://bit.ly/1ix1CbK)
Option 1 doesn't appear to give me what I need because the cell's display value is not exposed in the set of tokens they provide. Option 2 looks promising but it's not clear to me how to get at the cell's display value. The event argument only appears to contain the cell's backing value, which in my case is the GUID.
Is there a proper approach for using the group by functionality when you're also using an IEditorDataFilter implementation to convert values?
This may be frowned upon, but I asked my question on the Infragistic forums as well, and a complete answer is available there (along with an example solution demonstrating the problem):
http://www.infragistics.com/community/forums/p/88541/439210.aspx
In short, I was applying my custom editors at the cell level, which made them unavailable when the rows were grouped together. A better approach would be to apply the editor at the column level, which would make the editor available at the time of grouping, and would provide the expected behavior.
I am having a problem in QTP with selection of a web list box and I have exhausted what I know to do to resolve it. I am hoping someone can help.
There are 5 controls in a container, 2 webedit controls and 3 weblist controls. Together, they allow entry of accounts associated with a customer, and there can be 16 accounts for any customer. There are only ever five controls active at any time, whether editing or entering information for an account. When the information for an account is entered and accepted, it changes to a read-only table row and a new set of controls appears below it for entry of the next account.
The information entered in these controls is the account number, type, description, designation, and status. The status value is contingent on the designation, and the items in the list change dynamically depending on what the user specifies for the designation. The status list is not enabled until the designation is specified.
After some experimenting with timing, I was able to get past an issue where the status list for the first account was seen by QTP as disabled even though it was clearly enabled. I was then able to advance to entry of the second account.
I change the designation on the second account and try to select an appropriate item (specified in a data table) in the status list. My specification from the data table is never found. I figured it was a problem with verbiage differences and also that I should probably anticipate that and address it now, so I wrote a function to accept three parameters, the list and up to two search items. My function searches the listbox passed to it and looks for a match (full or partial) on the search items it receives. Here is where I encountered a significant problem.
The list of the control my function received was from the previous iteration of the test, corresponding to the designation of that account. This is why my function was not finding the selection item. The list on the screen shows the appropriate items, which suggests that I am looking at the wrong object. I also get the ‘object is disabled’ message when I put my data table value directly into the list with the select statement.
The active controls are displayed below the readonly presentation of the previously entered accounts. I am very new to QTP, but I also read documentation. My only theory at this point is that ATP is not passing the right list to my function… that perhaps that how it was learned included the position, which will change each time. However, the spy identifies the screen control as the same item I processed for the preceding account, which makes my theory suspect. In addition, the other four controls, which are not dynamically changing, do not present the same problem. I can put the information in them consistently.
I apologize for the length of this question, but I wanted to be as thorough and clear as possible. Can anyone help me get past this obstacle.
There are many possiblities why it is exposing this behaviour, so let's start with something simple:
Did you try a myWebList.Refresh call before you do something with the listbox? Refresh re-identifies the object.
Have you put a break point (red dot) inside the custom function. Just see what is happening there. With the debug viewer you can enter a realtime command in the scope of that function like msgbox myWebList.exist(0) or myWebList.Highlight
Can you see how the disabled property is propagated to the webpage? If you can 'Object Spy' it as TO property, you can add it in the GUI Map description.
A more sophisticated aproach is to create a Description with the weblist properties. If you can read the disabled property as an RO property from the 'Object Spy', you can use it as an identifier like "attribute/customDisabledProperty:=false".
If you cannot correctly read the disabled property, you can create a description object and do a count on the amount of items that match that description on that page with numberOfLists = Browser("my browser").Page("my page").ChildObjects(myDescription).Count and get the last list with Set lastList = Browser("my browser").Page("my page").ChildObjects(myDescription)(numberOfLists-1)
Keep us informed. Depending on how this works out, we can work into a direction for a solution.
I figured this out early this morning. There are 4 different list boxes used, each made visible or enabled dependent on the selection of the previous list. This is why the spy found the one listed when I was using it and also why the items in the list were not appropriate to what I had selected and also why it appeared disabled to QTP but enabled to me.
I was selecting the same designation when trying to spy it. It was intuitive that the controls were all the same. I am also a windows programmer and I would have populated the same list each time with the appropriate list items, and I presumed that was what the web developer was doing. It was not and it took some time to figure that out. Now that I figured it out, everything is working fine, and I came back to report that. This was a significant, time-intensive lesson.
Thank you very much for your input. It is still useful because I am very new to QTP and every thing I learn is of value.