I'm trying to use these enums with driver.get but it output as invalid argument. How to resolve this issue?
Here is my code:
public enum Url_1{
URL_LOGIN("http://localhost/wordpress/wp-login.php"),
URL_DASHBOARD("http://localhost/wordpress/wp-admin/"),
URL_NEWPOST("http://localhost/wordpress/wp-admin/post-new.php"),
URL_EDIT("http://localhost/wordpress/wp-admin/edit.php");
public String url;
private Url_1(String env_url){
this.url = env_url;
}
public String getUrl(){
return url;
}
}
public void setUp() {
WebDriver driver = getDriver(Browser.CHROME);
driver.get(String.valueOf(Url_1.URL_LOGIN));
}
driver.get(Url_1.URL_LOGIN.getUrl())
You need to call the getter (public String getUrl()), because otherwise your output will be equal to the name of the enum constant (E.g.: URL_LOGIN, URL_DASHBOARD, etc.). getUrl will retrieve the contents held by those constants.
Related
I have a config file with key value pair as
language = "IN"
and i have multiple page object enum files with name as
PageObject_US,PageObject_UK,PageObject_IN
every page object enum file has constants that can be accessed using for example
PageObjects_US.String.lable
but what i want to achieve is a way to create something like below
take the parameter from config file store it in a string
like String language = "IN"
Then concatenate using "PageObjects_" + language to get (PageObjects_IN)
so that the returned value can be used to fetch the constants from PageObjects_IN.String.label.
following is the code block:
if(!ENV.equalsIgnoreCase("development") && VALIDATION.equalsIgnoreCase("yes")) {
Elements.ByTitle(webDriver,PageObjects_IN.GREAT.label);
Elements.ByID(webDriver, PageObjects_IN.COUNTER.label);
}
In the above i want to use enum file PageObjects_IN at run time as i have many enum files
below is the enum
public enum PageObjects_IN {
// Text
GREAT("great"),
COUNTER("counter");
public final String lable;
PageObjects_IN(final String lable) {
this.lable = lable;
}
}
This is possible (using reflection) but strongly not recommended as it eliminates the efficiency of Java language constructs.
Not recommended way
Say you have a package click.webelement.cucumber.po where you store
public enum PO_EN {
GREAT("great_en"),
COUNTER("counter_en");
public final String label;
PO_EN(String label){
this.label = label;
}
}
and
public enum PO_IN {
GREAT("great_in"),
COUNTER("counter_in");
public final String label;
PO_IN(String label){
this.label = label;
}
}
Then to take a value you can do something like this:
String lang = "EN";
// Take class
Class clazz = Class.forName("click.webelement.cucumber.po.PO_" + lang);
// Find an object that represent enum constant
Object val = Arrays
.stream(clazz.getEnumConstants()).filter(o -> "GREAT".equals(o.toString()))
.findAny()
.get();
// Take field value for that object
Field f = clazz.getField("label");
System.out.println(f.get(val));
This is error-prone approach and you would not have benefit from compile phase.
Recommended approach - 1
Instead of having enum use classes.
public abstract class PO {
public abstract String great();
public abstract String counter();
}
and
public class PO_EN extends PO{
#Override
public String great() {
return "great_en";
}
#Override
public String counter() {
return "counter_en";
}
}
and
public class PO_IN extends PO{
#Override
public String great() {
return "great_in";
}
#Override
public String counter() {
return "counter_in";
}
}
so your test would be much simpler
String lang = "EN";
Class clazz = Class.forName("click.webelement.cucumber.po.PO_" + lang);
PO val = (PO) clazz.getDeclaredConstructor().newInstance();
System.out.println(val.great());
Recommended approach - 2
You can utilize PageFactory harness for your page objects and use this lib to parametrize your locators, like (if you use test ng):
#DataProvider(name = "languages")
Object[][] dataProvider(){
return new Object[][]{
{"en", "great_en", "counter_en"},
{"in", "great_in", "counter_in"}
};
}
#Test(dataProvider = "languages")
public void testPage(String language, String great, String counter){
DefaultParameterProvider
.properties
.set(Map.of("p.great", great, "p.counter", counter));
MyPage myPage = new MyPage(driver);
...
}
Where your page would be like this:
public class MyPage extends PageObjectParameterized {
#FindByParameterized(xpath = "//button[#name='{wec:p.great}']")
WebElement great;
#FindByParameterized(xpath = "//label[text()='{wec:p.counter}']")
WebElement counter;
#FindBy(xpath = "//input")
WebElement input;
public MyPage(SearchContext searchContext) {
super(searchContext);
}
}
I am trying to build an object which will be used to communicate with other objects. This communication object should have an enum, these enums include "ORDER_CREATED", "ORDER_CANCELLED" and "ORDER_AT_LOCATION". What I now want to do is assign a value to the enum "ORDER_AT_LOCATION" with a String location. This way there are no blank fields containing "null" if the enum is "ORDER_CREATED".
I am not entirely sure if this is even possible.
I tried using a constructor for one specific enum but didn't have any luck
public class OrderEvent {
private OrderEventTypes eventType;
}
enum OrderEventTypes{
//I want a constructor with String info only for the enum ORDER_AT_LOCATION
ORDER_AT_LOCATION{
String info;
public void ORDER_IN_TRANSIT(String info) {
this.info = info;
}
public String getInfo() {
return info;
}
}
, ORDER_CANCELLED, ORDER_COMPLETED, ORDER_CREATED;
}
the expected result should be that this statement works.
if(eventType.equals("ORDER_AT_LOCATION")) {
System.out.println(eventType.getInfo());
}
if you have any other nice solutions to this I would be very thankful, all the solutions I could come up with were perfectly do-able but not as nice as this would be.
You can create the enum with a constructor which accepts a String value and initialises the info field:
enum OrderEventTypes{
ORDER_AT_LOCATION("ORDER_AT_LOCATION"),
ORDER_CANCELLED,
ORDER_COMPLETED,
ORDER_CREATED;
private final String info;
OrderEventTypes(){
this("");
}
OrderEventTypes(String info){
this.info = info;
}
public String getInfo(){
return this.info;
}
#Override
public String toString() {
return this.info;
}
}
Now when you need to compare, you can use the getter to get the value of the info field:
if("ORDER_AT_LOCATION".equals(eventType.getInfo())){
System.out.println(eventType.getInfo());
}
I have an enum:
public enum ListEnums {
TEST("test1"),
TEST2("test2");
private final String txt;
ListEnums(String str){
txt = str;
}
#Override
public String toString(){return txt;}
I want get the enum string without call .toString().
Like:mymethod(ListEnums.TEST);
No: mymethod(ListEnums.TEST.toString());
Is it possible?
EDIT
The string return must be contains special chars.
here:
public enum ListEnums {
TEST("test1"),
TEST2("test2);
private final String txt;
ListEnums(String str){
txt = str;
}
#Override
public String toString(){
return txt;
}
if you call ListEnum.TEST.name() you will get TEST which is almost the same as calling toString()... if you instead do ListEnum.TEST then the name will be printed...
so Renaming the Enum constants is the way to go...
and the best part is: you will get rid off the constructor, the toString method and the variable txt...
you just dont need it anymore. :)
It's OK, and a good practice to use getters in your enums. Also good to keep your constructor private (though enums are private by default)....
public enum ListEnums {
TEST("test1"),
TEST2("test2");
private final String txt;
private ListEnums(String str){
txt = str;
}
public String getTxt() {
return txt;
}
}
public static void main(String[] args) {
System.out.println(ListEnums.TEST.getTxt());
}
We have an exception Class A with a few fault codes defined as public static final and it is referenced in many files (more than 100) in our source code.
We want all these fault codes in Class B for some processing.
Currently we have implemented a method called getFaultCodes() in Class A to build a list of fault codes and return the same. The problem with this approach is that whenever an fault code is introduced, it has to be added in getFaultCode method as well. This is error prone, as a user may forget to add the new code to the method.
Moving these fault codes under an enum requires changes in many files all over the source code, so we don't want do this.
class ExceptionA {
public static final String faultCode1 = "CODE1";
public static final String faultCode2 = "CODE1";
public static final String faultCode3 = "CODE1";
List<String> getFaultCodes(){
list.add(faultCode1);
......
return list;
}
}
We are thinking about using reflection, but I'm posting in this forum just to check if there is a better solution. Please provide your suggestion to solve this problem.
Maybe you can go through an interface:
public interface FaultCodeProvider
{
String getFaultCode();
}
Then have your enums implement it:
public enum DefaultFaultCodes
implements FaultCodeProvider
{
FAULT1("text for fault 1"),
// etc
;
private final String value;
DefaultFaultCodes(final String value)
{
this.value = value;
}
#Override
public String getFaultCode()
{
return value;
}
}
Collecting them from the enum is then as easy as cycling through the enum's values().
I have modified code code like below:
class ExceptionA {
public enum codes {
CODE1("CODE1"),
CODE2("CODE2"),
CODE3("CODE3"),
private String code;
codes(String code){
this.code = code;
}
public String getCode() {
return this.code;
}
}
public static final String faultCode1 = code.CODE1;
public static final String faultCode2 = code.CODE2;
public static final String faultCode3 = code.CODE3;
}
So that I need not to change the variables occurrences "faultCode" in the source code, I can access the list of fault codes from other class.
I've created a class called website, and want to access it like a variable so I can update values to it, probably better explained below:
Website w = new Website();
w.URL="stackoverflow.com";
Here's the code for the class:
class Website {
public String URL;
public Website(){
URL = "";
}
}
I would also like to add a method such as this:
public long save() {
return db.save(URL);
}
This (the method) isn't working for me at the moment
I would do it more OO way, hiding this URL variable from outside and letting change it's value from getter and setter methods. You can try this, maybe this will help.
In Website class
public class Website {
private String URL;
public Website(){
this.URL = "";
}
public void setUrl(String url) {
this.URL = url;
}
public String getUrl() {
return this.URL;
}
public long save() {
return db.save(this.URL);
}
}
And then call it
Website w = new Website();
w.setUrl("http://www.stackoverflow.com");
long someLongValue = w.save();