karate: Picking up feature files from absolute class path - cucumber

I am following the DemoTestSelected.java sample to run the feature file in my Karate Framework. It's working fine when i run them in intellij. But when i convert it into jar and then run from it, it is throwing the below error.
java.lang.RuntimeException: java.io.FileNotFoundException: file:\C:\Src_path\target\app-jar-with-dependencies.jar!\features\app\app_1.0.4_a.feature (The filename, directory name, or volume label syntax is incorrect)
I explored the Karate Core code and found the below class which might be problem.
public static URL toFileUrl(String path) {
path = StringUtils.trimToEmpty(path);
File file = new File(path);
try {
return file.getAbsoluteFile().toURI().toURL();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
I am stuck here, any help would be appreciated.

First - no one has ever reported this problem and teams normally don't need to bundle tests into a JAR.
Second - if you use the classpath: prefix, you should be able to load feature files from within even JAR files. So please use it and it is documented here: https://github.com/intuit/karate#reading-files
* def result = call read('classpath:some-reusable-steps.feature')
If this does not solve the problem, please follow the instructions here and submit an issue: https://github.com/intuit/karate/wiki/How-to-Submit-an-Issue - please explain what you are trying to do differently also.

Related

Groovy how can I build a custom library and use it in a project as dependency

I have a set of code procedures I use in a lot of places and I'm trying to basically move it to a library.
So I created my library with some unit test and everything was looking promising and at least working localy..
When I went to my project and deleted the files locally and then try to import them from my library as a dependency the code does not work.
I always get this kind of error
Class does not define or inherit an implementation of the resolved method abstract getProperty(Ljava/lang/String;)Ljava/lang/Object; of interface groovy.lang.GroovyObject.
I'm definitely not an expert on groovy but basically I use it in my Jenkins and Gradle for pipelines and some basic packaging or environment deployments.
I can show my class:
class ConsoleRow implements Comparable {
...
final Integer priority
final String rowStatus
final String message
final String rowReportClass
ConsoleRow(Integer priority, String status, String msg, String rowC) {
this.priority = priority
this.rowStatus = status
this.message = msg
this.rowReportClass = rowC
}
#Override
int compareTo(Object o) {
return this.priority <=> ((ConsoleRow) o).priority
}
The line that gives me the error is this actual compareTo when trying to do the "this.priority"
Caused by: java.lang.AbstractMethodError: Receiver class com.abc.insight.jenkins.ConsoleRow does not define or inherit an implementation of the resolved method abstract getProperty(Ljava/lang/String;)Ljava/lang/Object; of interface groovy.lang.GroovyObject.
at com.abc.insight.jenkins.ConsoleRow.compareTo(ConsoleRow.groovy:24)
at com.abc.insight.jenkins.ConsoleOutputHtmlBuilder.processOutput(ConsoleOutputHtmlBuilder.groovy:115)
at com.abc.insight.jenkins.ConsoleOutputHtmlBuilder.processOutput(ConsoleOutputHtmlBuilder.groovy)
at com.abc.insight.jenkins.ConsoleOutputHtmlBuilder.buildReport(ConsoleOutputHtmlBuilder.groovy:20)
at com.abc.insight.jenkins.ConsoleOutputHtmlBuilder$buildReport.call(Unknown Source)
at build_e548mc0tqjmi822clitlsycdk.runReport(C:\dev\repo\insight\insight-health-check\data-foundation\smoke-test\build.gradle:77)
The calling function is just trying to sort a list of those objects
List<ConsoleRow> outputRows = []
...
return outputRows.sort()
The part that gets me really confused is that if instead of importing the library as a dependency I just do this directly in this repo and put my sources in my buildSrc\src\main\groovy\com\abc\insight the code works fine...
So I really think it might be how I package and publish my library that might be wrong.
I'm really sure this is some basic error on my part because I never did a groovy library before but somehow I can't make it work.
It might be that my publication is just wrong, on my library side I'm using this plugins to do the publishing.
plugins {
id 'groovy'
id 'java-library'
id 'base'
}
publishing {
publications {
maven(MavenPublication) {
from components.java
}
}
}
I tried to change components.groovy but somehow it does not work.
Any ideas or tips, I think my question probably is showing some really lack of know-how on groovy but looking at the documentation and examples I could not figure it out.
Doing some debug in my IDE the compareTo that generates the exception looks like this.
public int compareTo(Object o) {
CallSite[] var2 = $getCallSiteArray();
return ScriptBytecodeAdapter.compareTo(this.priority, var2[0].callGroovyObjectGetProperty((ConsoleRow)ScriptBytecodeAdapter.castToType(o, ConsoleRow.class)));
}
I tried following this guide and code structure when doing moving the code to a library
https://docs.gradle.org/current/samples/sample_building_groovy_libraries.html
Thanks for any feedback
p.s: My code might look weird, I tried first to have everything with the def blablabla but I was having some issues with typecasting but I don't think this would be the reason for the problem I'm facing.
Anyway I got a look at the generated code in my IDE and I see a lot of get methods just no idea where they expected this getProperty from
Ok this was definitely a user error.
I am using distribution version of gradle 6.5.1
When I did the gradle init to bootstrap my project I was provided with the dependency of gradle groovy-all version 2.5.11
implementation group: 'org.codehaus.groovy', name: 'groovy-all', version: '2.5.11'
I thought that was a mistake and just updated to the latest version.
implementation group: 'org.codehaus.groovy', name: 'groovy-all', version: '3.0.9'
Now the problem is that the project in which I'm using the library is also running with gradle 6.5.1 so probably this version missmatch between compiple and usage was causing the problem.
By reverting to the correct version suggested by gradle the problem is gone.

Undefined steps after running test from TestRunner class

I have a very strange situation, I have created Features and Scenarios in the feature file and corresponding step definitions and methods in the separate class.
I have run tests by running a feature file, and everything was fine, all tests were green.
But, when I run tests from TestRunner class, I got the following message:
Undefined step: Given I am on the Facebook Login page and suggested code.
You can implement missing steps with the snippets below:
#Given("^I am on the Facebook Login page$")
public void i_am_on_the_Facebook_Login_page() throws Throwable {
// Write code here that turns the phrase above into concrete actions
throw new PendingException();
}
I have noticed that the suggested method have underscore:
(i_am_on_the_Facebook_Login_page())
but my methods do not have underscore
(iAmOnTheFacebookLoginPage())
Does anybody have an idea why this happens? I can't run tests now even from the feature file.
Recently, I have started using Mac and IntelliJ instead of Windows and Eclipse.
Is it possible that IntelliJ causes the problem?
P.S. I have used the option "Create step definition" from IntelliJ
ah...I figured out what the problem was...I forgot to put this piece of code
snippets = SnippetType.CAMELCASE
in CucumberOptions.
So, when I put this line of code here
#CucumberOptions(
plugin = {"pretty"},
features = {"src/test/resources/features"}, glue = {"/java/stepDefinitions"}, snippets = SnippetType.CAMELCASE)
everything works just fine.
It is possible your features folder is not in the build path (being a test folder) so Cucumber is unable to find it. Try this.

How can ConfigSlurper's groovy file can call methods defined in build.gradle?

I am working on project whose build logic is defined in gradle and has a build.gradle file for it. Now, we would like to manage property of the project using groovy's config Sluper. And, I have placed config.groovy file in folder that contains all the Helper class for the project. The content of the conf.groovy file is below:
categories {
includeCategories = defaultIncludeCategories()
excludeCategories = defaultExcludeCategories()
}
String defaultIncludeCategories() {
def include = 'default'
if( isAbcJob() ) {
include = 'tier0'
}
logger.info "defaultIncludeCategories: $include"
include
}
Now, as you can see there is a method name isAbcJob() that I need to use in the configuration file but this method is present in build.gradle, which is the file that call conf.groovy file for property management.
Bottom line is how would conf.groovy script would know where isAbcJob() method is?
Please advice.
I found the following question that has been asked on Gradle forums very helpful. And, it looks like that accessing other gradle script's methods is not possible unless you access them through tasks:
https://discuss.gradle.org/t/multiple-apply-froms-dont-seem-to-import-all-methods/2274/6

Default config.xml?

On this page of the documentation, at the bottom, it says:
You can find full examples of Sphinx-4 configuration file in sources. For example, check the file
sphinx4/src/apps/edu/cmu/sphinx/demo/transcriber/config.xml
Well, I looked, and there is no config.xml in that directory, and there is no such file in any of the other folders inside of demo either.
So where can one find a default config file to use to get started with?
If I just do Configuration configuration = new Configuration();, would that be good enough to start with?
I recently found out that what you suggest is not enough. Take a look at the latest code on the Github repository. There is a default.config.xml file at https://github.com/cmusphinx/sphinx4/tree/master/sphinx4-core/src/main/resources/edu/cmu/sphinx/api, and the path to it is set in the Context class in package edu.cmu.sphinx.api:
public Context(Configuration config)
throws IOException, MalformedURLException
{
this("../sphinx4/sphinx4-core/src/main/resources/edu/cmu/sphinx/api/default.config.xml", config);
}

Java getResourceAsStream cannot load resource

I am trying to load a class whose name is specified in a properties file. Here is the code for the same.
try {
Properties properties = new Properties();
InputStream in = MyAbstractFactory.class.getResourceAsStream("/some.properties");
properties.load(in);
String impl = properties.getProperty("key");
MyAbstractFactory factories = (MyAbstractFactory) Class.forName( impl ).newInstance();
return factories;
} catch (Exception e) {
return new DefaultFactoriesImpl();
}
This code is part of a jar file. the properties file is just outside the jar. Its unable to load the properties file and is loading DefaultFactoriesImpl instead. I know this happens when MyAbstractFactory.class.getResourceAsStream cant find the resource in the class path but that doesn't seem to be the case here.
Dir Structure:-
com
myjar.jar
some.properties
Command i am executing is "java -jar myjar.jar"
Any feedback on why this might be happening. Could this have something to do with Clasloaders? I'd like to add that when i run this code from within eclipse it seems pick up some.properties just fine.
Remove the leading slash from the argument you pass to getResourceAsStream().
Put the folder outside the JAR into the CLASSPATH when you execute the JAR. I don't know if the manifest CLASSPATH overrides the one you might pass using -cp. Play with it; one of them will work.
It's not finding your .properties file because it's not in the JVM CLASSPATH. When you do it properly, the JVM will find it.

Resources