I want to verify the placeholder text present in a text field using robotframework.
I have used different Selenium2Library keywords but none of them do precisely what I want.
Does anyone have an approach to getting this functionality from within my test?
You can run the command getAttribute(input_field_locator#placeholder). This will return you the text you want and then you can assert on it.
Once you have managed to access the functionality you are looking for from the REPL, you may find that it is not accessible via robotframework. You can expose new keywords by creating a wrapper for Selenium2Library which extends it with extra functionality - for an example see https://github.com/alistair-broomhead/scalable-robotframework-example/blob/master/TestLibraries/Selenium2Custom from a tutorial I am working on.
This example simply adds two keywords to robotframework on top of those in Selenium2Library if you instead import this class (Get Text and Get HTML, which are useful for verification):
from Selenium2Library import Selenium2Library
class Selenium2Custom(Selenium2Library):
"""
Custom wrapper for robotframework Selenium2Library to add extra functionality
"""
def get_text(self, locator):
"""
Returns the text of element identified by `locator`.
See `introduction` for details about locating elements.
"""
return self._get_text(locator)
def get_html(self, id=None):
"""
Get the current document as an XML accessor object.
"""
from lxml import html
src = self.get_source().encode('ascii', 'xmlcharrefreplace')
page = html.fromstring(src)
element = page.get_element_by_id(id) if id is not None else page
return html.tostring(element)
As such it would be trivial to do something like this:
from Selenium2Library import Selenium2Library
class Selenium2Custom(Selenium2Library):
"""
Custom wrapper for robotframework Selenium2Library to add extra functionality
"""
def get_placeholder(self, locator):
"""
Returns the placeholder text of element identified by `locator`.
"""
element = self._element_find(locator, True, False)
return element.get_attribute("#placeholder")
Now I don't know that this will definately work for you, but for me it works like so:
Python 2.7.3 (v2.7.3:70274d53c1dd, Apr 9 2012, 20:52:43)
[GCC 4.2.1 (Apple Inc. build 5666) (dot 3)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> from Selenium2Library import Selenium2Library
>>> def get_placeholder(self, locator):
... element = self._element_find(locator, True, False)
... return element.get_attribute("placeholder")
...
>>> Selenium2Library.get_placeholder = get_placeholder
>>> session = Selenium2Library()
>>> session.open_browser("http://www.wikipedia.org/wiki/Main_Page",
remote_url="http://127.0.0.1:4444/wd/hub")
1
>>> session.get_placeholder("search")
u'Search'
>>>
I also wanted to check placeholder text and after coming here and reading the comments, I got some clue about it. Now, the tricky part is how to do this in robot framework and after doing some math, I was able to do this pretty easily. Here is my answer in 2 lines:
${webelement}= Get WebElement locator
${placeholder}= Call Method ${webelement} get_attribute placeholder
Related
I have an API to get list of ids, name, data etc. (TestCase name GET-APIs_OrderdByID_ASC)
I want to transfer those IDs to other following TestCases in same TestSuite or other TestSuite.
In SOAPUI, Property Transfer works within TestSteps in same TestCase. (Using OpenSource version). I need to transfer the property value among different TestCases / TestSuites.
Below is the code that I can extract ids from one testCase and also name of testCases/testSteps where I want to transfer.
import com.eviware.soapui.impl.wsdl.teststeps.*
import com.eviware.soapui.support.types.StringToStringMap
import groovy.json.*
def project = context.testCase.testSuite.project
def TestSuite = project.getTestSuiteByName("APIs")
def TestCase = TestSuite.getTestCaseList()
def TestStep = TestCase.testStepList
def request = testRunner.testCase.getTestStepByName("List_of_APIs_OrderByID_ASC")
def response = request.getPropertyValue("Response")
def JsonSlurperResponse = new JsonSlurper().parseText(response)
def Steps = TestStep.drop(3)
log.info JsonSlurperResponse.data.id
def id = JsonSlurperResponse.data.id
Steps.each {
it.getAt(0).setPropertyValue("apiId", id.toString())
log.info it.getAt(0).name
}
If I run above code, all the array values of id [1, 2, 10, 11, 12, 13, 14, 15, 16, 17, 18] are set to each of the following testSteps
I looked some other SO questions
Property transfer in SOAPUI using groovy script
groovy-script-and-property-transfer-in-soapui
Can anyone help me out. :-)
I have done something with datasinks as Leminou suggests.
Datasinks are a good solution for this. In test A, create a datasink step to persist the values of interest. Then in the target step, use a data source step, which links to the file generated by the datasink earlier.
The data sink can be configured to append after each test or start afresh.
If you're struggling to tease out the values for the datasink, create a groovy step that returns the single value you want, then in the datasink step, invoke the groovy.
Sounds a little convoluted, but it works.
You can use project level properties or testSuiteLevel properties or testCase Properties.
This way you can achieve the same thing that you get from Property Transfer step but in a different way.
Write a groovy step in the source test case to setProperty(save values you want to use later)
testRunner.testCase.setPropertyValue("TCaseProp", "TestCase")
testRunner.testCase.testSuite.setPropertyValue("TSuiteProp","TestSuite")
testRunner.testCase.testSuite.project.setPropertyValue("ProjectLevel","ProjectLevelProperty")
"TCaseProp" is the name of the property. you can give any name
"TestCase" is the value you want to store. You can extract this value and use a variable
for example
def val="9000"
testRunner.testCase.setPropertyValue("TCaseProp", val)
You can use that property in other case of same suite. If you want to use across different suites you can define project level property
use the below syntax in target testcase request
${#Project#ProjectLevel}
${#TestCase#TCaseProp}
${#TestSuite#TCaseProp}
<convertCurrency>${#TestSuite#TCaseProp}</ssp:SystemUsername>
System will automatically replace the property value in above request
https://www.soapui.org/scripting-properties/tips-tricks.html <-- Helpful link which can explain in detail about property transfer
Well the following Script works.
Just to change as
Steps.each { s ->
id.each { i ->
s.getAt(0).setPropertyValue("apiId", i.toString())
}
}
Here id is a ArrayList type. So We can loop through the List.
PS: We can do the same using for loop.
I have a google-cloud-endpoints, in the docs, I did'nt find how to write a PATCH method.
My request:
curl -XPATCH localhost:8080/_ah/api/hellogreeting/1 -d '{"message": "Hi"}'
My method handler looks like this:
from models import Greeting
from messages import GreetingMessage
#endpoints.method(ID_RESOURCE, Greeting,`
path='hellogreeting/{id}', http_method='PATCH',
name='greetings.patch')
def greetings_patch(self, request):
request.message, request.username
greeting = Greeting.get_by_id(request.id)
greeting.message = request.message # It's ok, cuz message exists in request
greeting.username = request.username # request.username is None. Writing the IF conditions in each string(checking on empty), I think it not beatifully.
greeting.put()
return GreetingMessage(message=greeting.message, username=greeting.username)
So, now in Greeting.username field will be None. And it's wrong.
Writing the IF conditions in each string(checking on empty), I think it not beatifully.
So, what is the best way for model updating partially?
I do not think there is one in Cloud Endpoints, but you can code yours easily like the example below.
You will need to decide how you want your patch to behave, in particular when it comes to attributes that are objects : should you also apply the patch on the object attribute (in which case use recursion) or should you just replace the original object attribute with the new one like in my example.
def apply_patch(origin, patch):
for name in dir( patch ):
if not name.startswith( '__' ):
setattr(origin,name,getattr(patch,name))
I am trying to make general purpose image display class which
receives two parameters,
Key, and "Column location info in entity"
from URL and return and display specified image delivered from blob.
If you know what I am doing wrong, please give me a hint.
I have datastore "item" like below,
Key | image_index | image1 | image2 | image3 |
and I am requesting image with the URL like below,
http://stackoverwlow.com/image/{key}/{image_N}
I made url handler in the main like below,
def main():
application = webapp.WSGIApplication(
[('/', MainPage),
('/image/([^/]+)/([^/]+)', imageDisplay),
], debug=True)
wsgiref.handlers.CGIHandler().run(application)
and
I made imageDisplay class like below,
from google.appengine.ext import db
from google.appengine.ext import webapp
class imageDisplay(webapp.RequestHandler):
def get(self, _key, _size):
image = db.get(_key)
self.response.headers['Content-Type'] = 'image/jpg'
self.response.out.write(image._size)
But, if I try this code, it will return following error,
global name 'image_size' is not defined
If I specify which image in the entity should be displayed, it works.
So, the data is there.
self.response.out.write(image.image3)
My question is, how to specify "_size" from obtained entity "image"?
Thank you in advance.
With best regards
You need to fetch the attribute programmatically, like this:
self.response.out.write(getattr(image, size))
Since you're addressing your values like an array, you should probably just use one, though: use a db.ListProperty(db.Blob), instead!
I have modular project structure, like this:
./main.py
./app.yaml
../articles
.../__init__.py
.../models.py
../blog
.../__init__.py
.../models.py
../comments
.../__init__.py
.../models.py
I have defined models in file models.py for each package (this is application). I have defined next models for "comments" application:
class Comment(db.Model):
author = db.UserProperty(auto_current_user_add=True)
title = db.StringProperty(default="Title")
text = db.TextProperty("Message", default="Your message")
# references to any model
object = db.ReferenceProperty()
and in "articles" application I have defined next models:
class Article(db.Model):
author = db.UserProperty(auto_current_user_add=True)
title = db.StringProperty(default="Title")
text = db.TextProperty("Message", default="Your message")
1) On first loading of page - I create new article:
from articles.models import Article
article = Article(title="First article", text="This is first article")
article.put()
2) On second loading of page I create new comment:
from articles.models import Article
from comments.models import Comment
article = Article.get_by_id(1)
comment = Comment(title="First comment", text="This is first comment")
comment.put()
3) On thind loading of page, I want to see all comments for all articles, blogs, and other objects in whole datastore:
from comments.models import Comment
comments = Commen.all()
for comment in comments:
# print comment and article title
print "%s: %s" % (comment.title, comment.object.title)
Actual result: "KindError: No implementation for kind 'Article'"
Expected result: automatically detect object type for reference and load this class
See more on: http://code.google.com/p/appengine-framework/issues/detail?id=17
Project need your help!
In order to be able to return entities of a given kind, App Engine has to be able to find the Model class for it. There's no mechanism built in for doing so, because all it has to look it up with is the entity kind, which can be any arbitrary string.
Instead, import the modules containing the models you may reference from the module containing the Comment model. That way, any time you can perform a query on Comment, all the relevant models are already loaded.
In my project GAE framework I have solve this issue. On the first page loading I have load all models in memory.
What if we have models with the same name, for example Comment model in "blog" and "board" applications? In this case we have automatically add prefix for models for the King of this model. In result we have the different names for models in different applications: BlogComment and BoardComment.
You can learn more in source code to understand how we do this implementation.
I'm working on a data migration task, where I have to export a somewhat large Lotus Notes application into a blogging platform. My first task was to export the articles from Lotus Notes into CSV files.
I created a Agent in LotusScript to export the data into CSV files. I use a modified version of this IBM DeveloperWorks forum post. And it basically does the job. But the contents of the Rich Text field is stripped of any formatting. And this is not what I want, I want the Rich Text field rendered as HTML.
The documentation for the GetItemValue method explicitly states that the text is rendered into plain text. So I began to research for something that would retrieve the HTML. I found the NotesMIMEEntity class and some sample code in the IBM article How To Access HTML in a Rich Text Field Using LotusScript.
But for the technique described in the above article to work, the Rich Text field need to have the property "Store Contents as HTML and MIME". And this is not the case with my Lotus Notes database. I tried to set the property on the fields in question, but it didn't do the trick.
Is it possible to use the NotesMIMEEntity and set the "Store Contents as HTML and MIME" property after the content has been added, to export the field rendered as HTML?
Or what are my options for exporting the Notes database Rich Text fields as HTML?
Bonus information: I'm using IBM Lotus Domino Designer version 8.5
There is this fairly unknown command that does exactly what you want: retrieve the URL using the command OpenField.
Example that converts only the Body-field:
http://SERVER/your%5Fdatabase%5Fpath.nsf/NEW%5FVIEW/docid/Body?OpenField
Here is how I did it, using the OpenField command, see D.Bugger's post above
Function GetHtmlFromField(doc As NotesDocument, fieldname As String) As String
Dim obj
Set obj = CreateObject("Microsoft.XMLHTTP")
obj.open "GET", "http://www.mydomain.dk/database.nsf/0/" + doc.Universalid + "/" + fieldname + "?openfield&charset=utf-8", False, "", ""
obj.send("")
Dim html As String
html = Trim$(obj.responseText)
GetHtmlFromField = html
End Function
I'd suggest looking at Midas' Rich Text LSX (http://www.geniisoft.com/showcase.nsf/MidasLSX)
I haven't used the personally, but I remember them from years ago being the best option for working with Rich Text. I'd bet it saves you a lot of headaches.
As for the NotesMIMEEntity class, I don't believe there is a way to convert RichText to MIME, only MIME to RichText (or retain the MIME within the document for emailing purposes).
If you upgrade to Notes Domino 8.5.1 then you can use the new ConvertToMIME method of the NotesDocument class. See the docs. This should do what you want.
Alternativly the easiest way to get the Domino server to render the RichText will be to actually retrieve it via a url call. Set up a simple form that just has the RichText field and then use your favourite HTTP api to pull in the page. It should then be pretty straight forward to pull out the body.
Keep it simple.
Change the BODY field to Store contents as HTML and MIME
Open the doc in editmode.
Save.
Close.
You can now use the NotesMIMEEntity to get what you need from script.
You can use the NotesDXLExporter class to export the Rich Text and use an XSLT to transform the output to what you need.
I know you mentioned using LotusScript, but if you don't mind writing a small Java agent (in the Notes client), this can be done fairly easily - and there is no need to modify the existing form design.
The basic idea is to have your Java code open a particular document through a localhost http request (which is simple in Java) and to have your code capture that html output and save it back to that document. You basically allow the Domino rendering engine to do the heavy lifting.
You would want do this:
Create a form which contains only the rich-text field you want to convert, and with Content Type of HTML
Create a view with a selection formula for all of the documents you want to convert, and with a form formula which computes to the new form
Create the Java agent which just walks your view, and for each document gets its docid, opens a URL in the form http://SERVER/your_database_path.nsf/NEW_VIEW/docid?openDocument, grabs the http response and saves it.
I put up some sample code in a similar SO post here:
How to convert text and rich text fields in a document to html using lotusscript?
Works in Domino 10 (have not tested with 9)
HTMLStrings$ = NotesRichTextItem .Converttohtml([options] ) As String
See documentation :
https://help.hcltechsw.com/dom_designer/10.0.1/basic/H_CONVERTOHTML_METHOD_NOTESRICHTEXTITEM.html
UPDATE (2022)
HCL no longer support this method since version 11. The documentation does not include any info about the method.
I have made some tests and it still works in v12 but HCL recommended to not use it.
Casper's recommendation above works well, but make sure the ACL is such to allow Anonymous Access otherwise your HTML will be the HTML from your login form
If you do not need to get the Richtext from the items specifically, you can use ?OpenDocument, which is documented (at least) here: https://www.ibm.com/developerworks/lotus/library/ls-Domino_URL_cheat_sheet/
https://www.ibm.com/support/knowledgecenter/SSVRGU_9.0.1/com.ibm.designer.domino.main.doc/H_ABOUT_URL_COMMANDS_FOR_OPENING_DOCUMENTS_BY_KEY.html
OpenDocument also allows you to expand sections (I am unsure if OpenField does)
Syntax is:
http://Host/Database/View/DocumentUniversalID?OpenDocument
But be sure to include the charset parameter as well - Japanese documents were unreadable without specifying utf-8 as the charset.
Here is the method I use that takes a NotesDocument and returns the HTML for the doc as a string.
private string ConvertDocumentToHml(Domino.NotesDocument doc, string sectionList = null)
{
var server = doc.ParentDatabase.Server.Split('/')[0];
var dbPath = doc.ParentDatabase.FilePath;
string viewName = "0";
string documentId = doc.UniversalID.ToUpper();
var ub = new UriBuilder();
ub.Host = server;
ub.Path = dbPath.Replace("\\", "/") + "/" + viewName + "/" + documentId;
if (string.IsNullOrEmpty(sectionList))
{
ub.Query = "OpenDocument&charset=utf-8";
}
else
{
ub.Query = "OpenDocument&charset=utf-8&ExpandSection=" + sectionList;
}
var url = ub.ToString();
var req = HttpWebRequest.CreateHttp(url);
try
{
var resp = req.GetResponse();
string respText = null;
using (var sr = new StreamReader(resp.GetResponseStream()))
{
respText = sr.ReadToEnd();
}
return respText;
}
catch (WebException ex)
{
return "";
}
}