My first basic Cucumber program (Scenario) fails - Java - cucumber

I wrote my first Cucumber program today, and it fails. I wrote a very basic one, a simple scenario and it's step definition. Below is the feature file code and the step definition code.
Step Definiton code:
import cucumber.api.java.en.When;
import cucumber.api.java.en.Then;
public class Testing_Example1 {
#When("^I am on x page$")
public void i_am_on_x_page() throws Throwable {
System.out.println("I am on xPage");
}
#Then("^I see that element$")
public void i_see_that_element() throws Throwable {
System.out.println("I can see that page");
}
}
Feature File Code:
Feature: Testing
Scenario: s1
When I am on x page
Then I see that element
I have added the system variables as well - The JAVA_HOME and the maven variables as well and linked it to the PATH variable I system variables.
I have added dependencies in the POM file, such as the Cucumber-Java, Cucumber-Junit and for selenium as well and yet my program fails and says the steps are undefined.
Output:
1 Scenarios (1 undefined)
2 Steps (2 undefined)0m0.000s
You can implement missing steps with the snippets below:
#When("^I am on x page$")
public void i_am_on_x_page() throws Throwable {
// Write code here that turns the phrase above into concrete actions
throw new PendingException();
}
#Then("^I see that element$")
public void i_see_that_element() throws Throwable {
// Write code here that turns the phrase above into concrete actions
throw new PendingException();
}
Undefined step: When I am on x page
Undefined step: Then I see that element
Process finished with exit code 0
I guess it's because my feature file is not getting linked with the step definition file, but I don't understand what is missing that the feature file does not execute properly and scenarios fail. Someone who has knowledge about this, do help.
Thank You!

I found the solution to this. I just edited the configuration of the feature file - > edit configurations -> Paste the path of the package in which your step definition file is present -> apply.
I just has to link the feature file to the step definition using Glue.

Specify the stepdefintion & feature file details in your cucumber runner class.
#CucumberOptions(
plugin={"pretty", "html:target/cucumber-html-report","json:target/cucumber-report.json"},
features = "src/test/resources",
glue ="com.vg.pw.ui.stepdefinitions",
)
public class CucumberRunner {
...
}

Related

Screenshot with Cucumber Groovy

I am working with Cucumber features and Groovy as Step definitions in Katalon Studio. As we have each step in the step definition and wanted to take a screenshot when the step is failed (AShot or whatever). I would like to have the code to take the snap and would like to know do we need this in each step definition file.
I saw this similar question in this forum but does not have a clear answer.
Please note that I know the option in “Take Screenshot when execution failed” in settings.
Can you please provide the sample on this to proceed further?
Try adding the following to your #After test hook (or Test Listeners):
#After
public void TearDown(Scenario scenario) {
if (scenario.isFailed()) {
WebDriver driver = DriverFactory.getWebDriver()
byte[] screenshot = ((TakesScreenshot)driver).getScreenshotAs(OutputType.BYTES);
scenario.embed(screenshot, "image/png");
scenario.write(scenario.getName());
}
}
You will need some imports:
import cucumber.api.Scenario;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.TakesScreenshot;
import com.kms.katalon.core.webui.driver.DriverFactory;
(Or just pres Ctrl + Shift + O to automatically import the missing classes.)
1st you are planning to run as a test suite of your test pack, you don't need to add any code to capture screenshots, Katalon will automatically do that.
for running as a test case use below example
public void catchNotyMessage(){
TestObject noty_warning = WebUI.modifyObjectProperty(findTestObject("DUMMY"), 'css', 'equals', 'div.noty_type_warning', true)
TestObject noty_error = WebUI.modifyObjectProperty(findTestObject("DUMMY"), 'css', 'equals', 'div.noty_type_error', true)
if (WebUI.verifyElementPresent(noty_error, 1, FailureHandling.OPTIONAL)){
this.takeWebElementScreenshot(noty_error)
}
else if (WebUI.verifyElementPresent(noty_warning, 1, FailureHandling.OPTIONAL)){
this.takeWebElementScreenshot(noty_warning)
}
}

Java Cucumber: How to get string parameter values from all the steps in a single scenario

I'm looking for a way to get all the parameters that are being passed in each step before entering the actual scenario for each scenario in my feature file.
Sample feature file:
Feature: Login action
Background:
When "{login url}" is open
Scenario: Registered user provides valid username and password
Given user enters username "{username}" and password "test password"
And user clicks on "btnLogin"
Then user is logged in
Parameters I want to get:
{login url}
{username}
password
btnLogin
What I tried so far:
I have tried using a common hook that will be automatically used by all of my scenarios:
public class ScenarioHook {
public ScenarioHook() {
}
#Before
public void setupScenario(Scenario scenario) throws InterruptedException {
//Here I am currently watching the {scenario} object and I can see all the steps
//but I still dont know where to get the passed parameter values.
}
#After
public void teardownScenario() throws InterruptedException {
}
}
UPDATE 1:
The reason why I want to do this is I want to manipulate the strings (if possible). e.g. all data enclosed in "{}" will be transformed to something else before entering the actual scenario.
You can use the #Transform annotation to change the value of the parameter to the step definition.
For this you will need to create a class which contains the logic of the string modification and will return the modified value.
public class StringTransformer extends Transformer<String>{
public String transform(String value) {
return "transformed "+value;
}
}
Next you need to include this class in your stepdefinition using the #Transform annotation in front of the method argument.
#When("^Login with (.*?)$")
public void helloHere(#Transform(StringTransformer.class) String userName)
{
System.out.println("TEXT --- " + userName);
}
This should give you the new transformed string. You can use this to create objects from your initial string. (Actually that is what it is used for)
Cucumber Sceanario class will not provide you this information as I don't think all steps are actually being loaded and parsed before starting executing the scenario but parsed one by one during the scenario execution. One option I can think of is to create a background step where you will manually include all parameters involved in the scenario. For example:
Feature: Login action
Background:
Given these parameters are using within this scenario: "{login url}", "{username}", "password", "btnLogin"
When "{login url}" is open

Groovy - Type check AST generated code

I have a Groovy application that can be custimized by a small Groovy DSL I wrote. On startup, the application loads several Groovy scripts, applies some AST transformations and finally executes whatever was specified in the scripts.
One of the AST transformations inserts a couple of lines of code into certain methods. That works fine and I can see the different behavior during runtime. However, sometimes the generated code is not correct. Although I load the scripts with the TypeChecked customizer in place, my generated code is never checked for soundness.
To show my problem, I constructed an extreme example. I have the following script:
int test = 10
println test // prints 10 when executed without AST
I load this script and insert a new line of code between the declaration of test and println:
public void visitBlockStatement(BlockStatement block) {
def assignment = (new AstBuilder().buildFromSpec {
binary {
variable "test"
token "="
constant 15
}
}).first()
def newStmt = new ExpressionStatement(assignment)
newStmt.setSourcePosition(block.statements[1])
block.statements.add(2, newStmt)
super.visitBlockStatement(block)
}
After applying this AST, the script prints 15. When I use AstNodeToScriptVisitor to print the Groovy code of the resulting script, I can see the new assignment added to the code.
However, if I change the value of the assignment to a String value:
// ...
def assignment = (new AstBuilder().buildFromSpec {
binary {
variable "test"
token "="
constant "some value"
}
}).first()
// ...
I get a GroovyCastExcpetion at runtime. Although the resulting script looks like this:
int test = 10
test = "some value" // no compile error but a GroovyCastException at runtime here. WHY?
println test
no error is raised by TypeChecked. I read in this mailing list, that you need to set the source position for generated code to be checked, but I'm doing that an it still doesn't work. Can anyone provide some feedback of what I am doing wrong? Thank you very much!
Update
I call the AST by attaching it to the GroovyShell like this:
def config = new CompilerConfiguration()
config.addCompilationCustomizers(
new ASTTransformationCustomizer(TypeChecked)
)
config.addCompilationCustomizers(
new ASTTransformationCustomizer(new AddAssignmentAST())
)
def shell = new GroovyShell(config)
shell.evaluate(new File("./path/to/file.groovy"))
The class for the AST itself looks like this:
#GroovyASTTransformation(phase = CompilePhase.CANONICALIZATION)
class AddAssignmentAST implements ASTTransformation {
#Override
public void visit(ASTNode[] nodes, SourceUnit source) {
def transformer = new AddAssignmentTransformer()
source.getAST().getStatementBlock().visit(transformer)
}
private class AddAssignmentTransformer extends CodeVisitorSupport {
#Override
public void visitBlockStatement(BlockStatement block) {
// already posted above
}
}
}
Since my Groovy script only consists of one block (for this small example) the visitBlockStatement method is called exactly once, adds the assignment (which I can verify since the output changes) but does not ever throw a compile-time error.

Revit Api Load Command - Auto Reload

I'm working with the revit api, and one of its problems is that it locks the .dll once the command's run. You have to exit revit before the command can be rebuilt, very time consuming.
After some research, I came across this post on GitHub, that streams the command .dll into memory, thus hiding it from Revit. Letting you rebuild the VS project as much as you like.
The AutoReload Class impliments the revit IExteneralCommand Class which is the link into the Revit Program.
But the AutoReload class hides the actual source DLL from revit. So revit can't lock the DLL and lets one rebuilt the source file.
Only problem is I cant figure out how to implement it, and have revit execute the command. I guess my C# general knowledge is still too limited.
I created an entry in the RevitAddin.addin manifest that points to the AutoReload Method command, but nothing happens.
I've tried to follow all the comments in the posted code, but nothing seems to work; and no luck finding a contact for the developer.
Found at: https://gist.github.com/6084730.git
using System;
namespace Mine
{
// helper class
public class PluginData
{
public DateTime _creation_time;
public Autodesk.Revit.UI.IExternalCommand _instance;
public PluginData(Autodesk.Revit.UI.IExternalCommand instance)
{
_instance = instance;
}
}
//
// Base class for auto-reloading external commands that reside in other dll's
// (that Revit never knows about, and therefore cannot lock)
//
public class AutoReload : Autodesk.Revit.UI.IExternalCommand
{
// keep a static dictionary of loaded modules (so the data persists between calls to Execute)
static System.Collections.Generic.Dictionary<string, PluginData> _dictionary;
String _path; // to the dll
String _class_full_name;
public AutoReload(String path, String class_full_name)
{
if (_dictionary == null)
{
_dictionary = new System.Collections.Generic.Dictionary<string, PluginData>();
}
if (!_dictionary.ContainsKey(class_full_name))
{
PluginData data = new PluginData(null);
_dictionary.Add(class_full_name, data);
}
_path = path;
_class_full_name = class_full_name;
}
public Autodesk.Revit.UI.Result Execute(
Autodesk.Revit.UI.ExternalCommandData commandData,
ref string message,
Autodesk.Revit.DB.ElementSet elements)
{
PluginData data = _dictionary[_class_full_name];
DateTime creation_time = new System.IO.FileInfo(_path).LastWriteTime;
if (creation_time.CompareTo(data._creation_time) > 0)
{
// dll file has been modified, or this is the first time we execute this command.
data._creation_time = creation_time;
byte[] assembly_bytes = System.IO.File.ReadAllBytes(_path);
System.Reflection.Assembly assembly = System.Reflection.Assembly.Load(assembly_bytes);
foreach (Type type in assembly.GetTypes())
{
if (type.IsClass && type.FullName == _class_full_name)
{
data._instance = Activator.CreateInstance(type) as Autodesk.Revit.UI.IExternalCommand;
break;
}
}
}
// now actually call the command
return data._instance.Execute(commandData, ref message, elements);
}
}
//
// Derive a class from AutoReload for every auto-reloadable command. Hardcode the path
// to the dll and the full name of the IExternalCommand class in the constructor of the base class.
//
[Autodesk.Revit.Attributes.Transaction(Autodesk.Revit.Attributes.TransactionMode.Manual)]
[Autodesk.Revit.Attributes.Regeneration(Autodesk.Revit.Attributes.RegenerationOption.Manual)]
public class AutoReloadExample : AutoReload
{
public AutoReloadExample()
: base("C:\\revit2014plugins\\ExampleCommand.dll", "Mine.ExampleCommand")
{
}
}
}
There is an easier approach: Add-in Manager
Go to Revit Developer Center and download the Revit SDK, unzip/install it, the check at \Revit 2016 SDK\Add-In Manager folder. With this tool you can load/reload DLLs without having to modify your code.
There is also some additional information at this blog post.
this is how you can use the above code:
Create a new VS class project; name it anything (eg. AutoLoad)
Copy&Paste the above code in-between the namespace region
reference revitapi.dll & revitapiui.dll
Scroll down to AutoReloadExample class and replace the path to point
your dll
Replace "Mine.ExampleCommand" with your plugins namespace.mainclass
Build the solution
Create an .addin manifest to point this new loader (eg.
AutoLoad.dll)
your .addin should include "FullClassName" AutoLoad.AutoReloadExample
This method uses reflection to create an instance of your plugin and prevent Revit to lock your dll file! You can add more of your commands just by adding new classes like AutoReloadExample and point them with seperate .addin files.
Cheers

How to set TestName in CodedUI?

I have a data driven CodedUI test method named myTestMethod, which uses XML for supplying input data.
For each run on a data set, CodedUI reports something like this in the Test Explorer:
Test Passed - myTestMethod (Data Row 0)
Test Passed - myTestMethod (Data Row 1)
Test Failed - myTestMethod (Data Row 2) <error details>
Test Failed - myTestMethod (Data Row 3) <error details>
I was wondering is there is a way to set the test name to something more identifiable (probably from the input data set itself).
Seems like CodedUI uses TestContext.TestName for this reporting purpose, but, it is a readonly property. Is there a way to set it somewhere else, somehow?
Please help.
Thanks,
Harit
Ok i understand you now. I actually have a class where i write general functions. One of them is for save the test results as i want.
I use data driven based in XML. then my Employe1 and Employe2 are different runs of the same test_method.
Just locate [TestCleanup()] and call here a function to save a log has you need.
Log can be saved in csv format, plain text separated by ; for example with StreamWriter.
namespace NAME_SPACE
{
[CodedUITest]
public class Program_Something_BlaBla
{
Stopwatch stopWatch = new Stopwatch();
[TestMethod(), Timeout(999999999)]
[DataSource("Microsoft.VisualStudio.TestTools.DataSource.XML", PATH_XML, "DATOS", DataAccessMethod.Sequential)]
public void Program_Something_BlaBla_Method()
{
string employe = TestContext.DataRow["EMPLOYE"].ToString();
try
{
//Test actions
...
{
catch (Exception g)
{
...
return;
}
}
#region Additional test attributes
// You can use the following additional attributes as you write your tests:
////Use TestInitialize to run code before running each test
[TestInitialize()]
public void MyTestInitialize()
{
stopWatch.Start();
...
}
//Use TestCleanup to run code after each test has run
[TestCleanup()]
public void MyTestCleanup()
{
stopWatch.Stop();
...
Common.EndTest(employe);
}
#endregion
Hope it helps,
I don't want to say it's impossible, but the Test Explorer in populated at compile time and the data would be pulled in at run time.
I don't think this would be possible. The only way for you is to read the generated "TRX" file ( as it is xml) and replace the values by reading your csvs. Might need to do a tool but the overhead is huge.

Resources