I would like to ask If there is a possibility to log python keywords to log.html like robot keywords. If we executin Robot/Python keyword from robot file it's ok - there is a "node" for keyword. When we run python keyword and if that keyword contain other keywords inside, these keywords are not logged properly - doesn't have own node. In log.html that keywords are under one "node" (parent), executed from robot file.
Is there any decorator for keywords or other method to "tell" for robot that methods inside that keyword are too keywords?
Robot:
Run Something
+Run other keyword
+Execute command
Python:
- Run something
....
....
Thank you in advance for your help.
Br, Tomasz
Your image in comments helped me to realize your problem.
Is there any decorator for keywords or other method to "tell" for robot that methods inside that keyword are too keywords?
As I know, there isn't such decorator. Robot has no knowledge about internal call-graph of a Python keyword and is unable to produce tree-like structure for logs of your internal function calls.
I think, there is a workaround for that. Logging and return value are the only ways that you can communicate to Robot Framework from within your Python code and tell it something. I suggest you to use logging API to make your Robot Framework log more structured and this decorator is one of several things you can do:
from robot.api import logger
def logged_keyword(some_function):
def wrapper():
logger.info('start of {}'.format(some_function.__name__))
some_function()
logger.info('end of {}'.format(some_function.__name__))
return wrapper
def show_my_name():
logger.info('Tommy')
print_colour()
#logged_keyword
def print_colour():
logger.info('blue')
print_other_colour()
#logged_keyword
def print_other_colour():
logger.info('white')
There is a way to tell to Robot Framework that you are logging HTML rather than plain text; so, you can use a decorator to log HTML mark-ups to help Robot Framework structure your log messages. Maybe the HTML source of Robot Framework log is a good place to start (inspect element in browser).
def markuped_keyword(some_function):
def wrapper():
logger.info('<div>', html=True)
some_function()
logger.info('</div>', html=True)
return wrapper
You should refine the mark-up to have a tree-like structure for your logs.
Good luck!
Related
I have .robot file containing Suite setup and few testcases say Test1, Test2 and Test3 . I want to run Test2. But as part of requirement I need to print the current testcase name being executed (i.e. Test2 )in suite setup. As suite setup gets executed before testcase, ${TEST_NAME} cannot be used. Is there any other way to retrieve the current testcase name? . Please help me !
I think your best option is to use visitor interface.
You'd create a new class where you'll iterate over all the tests:
Libraries/Visitor.py
from robot.model.visitor import SuiteVisitor
from robot.api import logger
class Visitor(SuiteVisitor):
def start_suite(self, suite):
for test in suite.tests:
logger.console("{}".format(x))
Then you'd run your tests with --prerunmodifier option where you'll specify your new class like so: --prerunmodifier Libraries/Visitor.py.
It'll list your test cases first and then start executing them.
I'm just getting started with Flow, trying to introduce it into an existing Node codebase.
Here are two lines Flow complains about:
import Module from 'module';
const nodeVersion = Number(process.versions.node.split('.')[0]);
The warnings about these lines are, respectively:
module. Required module not found
call of method `split`. Method cannot be called on possibly null value
So it seems like Flow isn't aware of some things that are standard in a Node environment (e.g. process.versions.node is guaranteed to be a string, and there is definitely a Node builtin called module).
But then again, Flow's configuration docs suggest it's Node-aware by default. And I have plenty of other stuff like import fs from 'fs'; which does not cause any warning. So what am I doing wrong?
Module fs works as expected because Flow comes with built-in definitions for it, see declare module "fs" here: https://github.com/facebook/flow/blob/master/lib/node.js#L624
Regarding process.versions.node, you can see in the same file that the versions key is typed as a map of nullable strings, with no mention of the specific node property: versions : { [key: string] : ?string };. So you'll need to either make a PR to improve this definition, or adjust your code for the possibility of that value being null.
I guess the answer about module "module" is obvious now – there are no built-in definitions for that module in Flow in lib/node.js. You could write your own definitions, and optionally send a PR with them to the Flow team. You can also try searching github for these, someone might have done the work already.
That lib directory is very useful by the way, it has Flow definitions for DOM and other stuff as well.
Background:
I have created a basic playground project that contains:
A testLogin.java file that contains:
a. testng package imports (org.testng.*)
b. selenium webdriver imports (org.openqa.selenium.*)
c. 5 test-methods with testng annotations:
#Test(groups={"init"})
public void openURL()
Contains webdriver code to initiate the webdriver and open a chrome >instance with a given url.
#Test(dependsOnGroups={"init"})
public void testLogin()
Contains webdriver code to:
1. Locate username password text-input elements, enter the username password from a properties file.
2. Locate the "log in" button and click the button to log-in
3. Manage a login-forcefully scenario if someone else has already logged in using the credentials.
#Test(dependsOnMethods={"testLogin"})
public void testPatientsScheduleList()
Contains webdriver code to check if any patients have been scheduled. If yes, then fetch the names and display in console.
#Test()
public void testLogout()
Contains webdriver code to locate the logout button and click on the button to logout of the app.
#AfterTest()
public void closeConnection()
Contains webdriver code to dispose the webdriver object and close the chrome instance.
Currently I am simply running the test script wrapped as testng methods from ANT and a testng-xslt report gets generated.
Issues:
1. Performing validations against every line of code of webdriver script in a test method:
I know:
1. Selenium webdriver script contains API methods (findElement() and others.) that throw exceptions as a result of a default assertion/validation they perform. These exceptions show up in the generated report when a test-method fails.
2. TestNG provides Assert class that has many assertion methods but I have not yet figured out how can i use them to perform validation/assertions against every line of code of webdriver script. I tried adding assertion methods after every line of webdriver script code. What appeared in the output was just an AssertionError exception for a testmethod.
2. Failing a certain test method which gets passed due to try.. catch block.
If I use a try catch block around a set of 2 or more test drive script steps, and if a test-case fails in any of the steps (script line) then the try..catch block handles it thereby showing the test-method as "passed" in the execution report, which actually failed.
3. Creating a custom report which will show desired test execution results and not stack-traces!
When I execute the above script, a testng-xslt report gets generated that contains pass/fail status of each test method in a test-suite (configured in testng.xml).
The test-results only give me whether a test-method has passed or failed and provides an exception's stack-trace which really doesn't provide any helpful information.
I don't want such abstract level of test execution results but something like:
Name | Started | Duration | What-really-went-wrong (Failure)
Can anyone please suggest/ give some pointers regarding:
1. How can I perform validation/assertion against every line of code of webdriver script in a test-method without writing asserts after every script line?
2. How can I fail a certain test method which gets passed due to try catch block?
3. How can I customize the failure reporting so that I can send a failure result like "Expected element "button" with id "bnt12" but did not find the element at step 3 of test-method" to testng's reporting utility?
4. In the testng-xslt report I want to display where exactly in the test-method a failure occurred. So for example if my test-method fails because of a webelement = driver.findElement() at line 3 of a test-method, I want to display this issue in the test-report in the "What-really-went-wrong" column. I have read about testng testlisteners TestListenerAdapter / ITestListener/ IReporter but I don't understand how to use them after checking testng's javadocs.
5. Also, I have to implement PageObject pattern once I am done with customizing the test report. Where would be the right place to perform assertions in a page-object pattern? Should assertions be written in the page object test methods or in the higher level test methods that will use the PageObject classes?
P.S: I am completely new to testng framework and webdriver scripting. Please bear with any technical mistakes or observation errors if any in the post.
How can I perform validation/assertion against every line of code of webdriver script in a test-method without writing asserts after
every script line?
I dont think so. It is the assertions that does the comparison. So u need it.
How can I fail a certain test method which gets passed due to try catch block?
try-catch will mask the assertion failure.(because on assertion failure, an assertion exception is thrown, so if your catch block is like (catch(Exception e)) Assertion failures wont escape the catch block.
How can I customize the failure reporting so that I can send a failure result like "Expected element "button" with id "bnt12" but did
not find the element at step 3 of test-method" to testng's reporting
utility?
You need to use test listeners . TestNG TestListenerAdapter is a good start
Also, I have to implement PageObject pattern once I am done with
customizing the test report. Where would be the right place to perform
assertions in a page-object pattern? Should assertions be written in
the page object test methods or in the higher level test methods that
will use the PageObject classes?
My personal choice is to use assertions in Test methods, since it is where we are doing the actual testing. Page objects contains scripts for navigating inside the web page.
How can I customize the failure reporting so that I can send a failure
result like "Expected element "button" with id "bnt12" but did not
find the element at step 3 of test-method" to testng's reporting
utility?
You can use extent report and testng listener class( in this class use onTestFailure method to customize your failure report).
I found that some options in CompilerOption are not exported to the command line.
For example, alias all strings is available in the Closure Compiler's Java API CompilerOption but I have no idea how set this in the command line.
I know I can create a new java class, like:
Compiler c = new Compiler();
ComppilerOptions opt = new ComppilerOptions();
opt.setAliasAllString(true);
c.compile(.....);
However I have to handle the command line args myself.
Any simple idea?
============================
In order to try the alias all string option, I write a simple command line application based on compiler.jar.
However I found that, the result I got when open the alias all string is not what I expected.
For example:
a["prototype"]["say"]=function(){
var a="something string";
}
Given the above code, the something string will be replaced by a variable like this:
var xx="something string";
....
var a=xx;
....
This is fine, but how about the string "say"? How does the closure compiler know this should be aliased(replace it use variable) or exported(export this method)?
This is the compiled code now:
a.prototype.say=function(){....}
It seems that it export it.
While I want this:
var a="prototype",b="say",c="something string";
xx[a][b]=function(){.....}
In fact, this is the google_map-like compilation.
Is this possible?
Not all options are available from the command line - this includes aliasAllStrings. For some of them you have the following options:
Build a custom version of the compiler
Use the Java API (see example).
Use plovr
Getting the same level of compression and obfuscation as the Maps API requires code written specifically for the compiler. When properly written, you'll see property and namespace collapsing, prototype aliasing and a whole host of others. For an example of the style of code that will optimize that way, take a look at the Closure Library.
Modifying http://code.google.com/p/closure-compiler/source/browse/trunk/src/com/google/javascript/jscomp/CompilationLevel.java?r=706 is usually easy enough if you just want to play with something.
Plovr (a Closure build tool) provides an option called experimental-compiler-options, which is documented as follows:
The Closure Compiler contains many options that are only available programmatically in Java. Many of these options are experimental or not finalized, so they may not be a permanent part of the API. Nevertheless, many of them will be useful to you today, so plovr attempts to expose these the experimental-compiler-options option. Under the hood, it uses reflection in Java, so it is fairly hacky, but in practice, it is a convenient way to experiment with Closure Compiler options without writing Java code.
In Flash/Flex, is it possible to capture the result of 'trace' in code?
So, for example, if one part of the code calls trace("foo"), I'd like to automatically capture the string "foo" and pass it to some other function.
Edit: I'm not interested in trying to use trace instead of a proper logging framework… I want to write a plugin for FlexUnit, so when a test fails it can say something like: "Test blah failed. Here is the output: ... traced text ...".
Edit 2: I only want to capture the results of trace. Or, in other words, even though my code uses a proper logging framework, I want to handle gracefully code that's still using trace for logging.
As far as I know it's impossible to do it externally, google brings up no results. Have you considered creating a variable for the output and then adding that to the log, eg:
var outputtext = "text";
trace(outputtext);
// log outputtext here
Disregard if it isn't feasible, but I can't think of any other way.
However you can do it internally, if it's just for development purposes: http://broadcast.artificialcolors.com/index.php?c=1&more=1&pb=1&tb=1&title=logging_flash_trace_output_to_a_text_fil
If you want to write traces to a log, you can just use the Debug version of Flash Player and tell it to log traces.
I have a Debug.write method that sends the passed messages over a LocalConnection which I use that instead of trace. My requirement is to be able to capture the debug statements even when the SWF is running out of the authoring environment, but you can use this method to capture the trace messages.
As far as I understood you don't want to use logging, which is of course the right way to do it.
So, you can simply create a Static class with method trace, and call this method from anywhere in the application, that's how you will get all traces to one place, then could do what ever you want with the trace string before printing it to console.
Another way is to create bubbling trace event and dispatch it whenever you want to trace message, then add listener to STAGE for it and catch all events...
Hope its help
I would suggest looking through the source for the swiz framework. They use the flex internal logLogger app-wide and use best practices in a good majority of their code.