Not sure how other corporations are localizing Selenium. It has been an issue with ours. Since the creation of selenium we have not embedded localization into the infrastructure…oops, right?! The funny thing is that it took two of us to implement this simple solution in a couple hours. Once done we sent it off for review by the Automation Testing team. I wanted to let others take a look in case they were in the same situation that we were in.
One key is that we call into our Java server using a JSP would change depending upon how you get your localization entries for selenium.
How we localized Selenium:
•Added a class RBUtil that has methods overloaded method getValue(). As an example it is used in the following way:
1 2 3 4 5 | String localizedValue = RBUtil.getValue(KEY_TO_LOCALIZATION) //There are also signatures for the following: RBUtil.getValue(key, default) RBUtil.getValue(key, text insert array) |
• The way this works is by calling the server with the resource bundle key. We are using the same Tomcat session as selenium to get the localized value.
• A key is that we are re-using the Tomcat session id so that we are not creating new sessions for each resource bundle (or localized string).
• We also cache the locale, username, etc. In fact, we will probably need to do more caching in the future but the main goal is that this will get us on our feet for having selenium localized.
Implementation Class:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 | package com.ptc.selenium.localization; import java.io.BufferedReader; import java.io.InputStream; import java.io.InputStreamReader; import java.net.URL; import java.net.URLConnection; import java.util.List; import org.apache.log4j.Logger; import sun.misc.BASE64Encoder; import com.ptc.selenium.SeleniumLogger; import com.ptc.selenium.SeleniumSession; import com.ptc.selenium.SolventSelenium; import com.ptc.selenium.SolventTestCase; /** * Singleton class that is used to get the localization values from the RBInfo class file entries. * * This will retrieve values for selenium tests to be able to localize and attribute clicks to rbinfo files. * */ public class RBUtil { private static final Logger log = SeleniumLogger.getLogger(SolventTestCase.class.getName()); private static RBUtil singleton; private final String baseURL; private final String username; private final String password; private final String cookie; private final String locale; private RBUtil() { SolventSelenium selenium = SeleniumSession.get(); // Cache these values on the instance baseURL = selenium.getBaseURL(); password = selenium.getPassword(); username = selenium.getUsername(); cookie = selenium.getCookieByName("JSESSIONID"); locale = selenium.getEval("selenium.browserbot.getCurrentWindow().getLocale()"); } public static RBUtil getInstance() { if (singleton == null) { singleton = new RBUtil(); } return singleton; } /** * Will retrieve the resource bundle value given the key in the form of class.key. For example, * com.ptc.windchill.enterprise.folder.folderResource.PARTS_VIEW * * @param key * In the form of CLASS.KEY. For example, * "com.ptc.windchill.enterprise.folder.folderResource.PARTS_VIEW". * @return The value returned from the resource bundle lookup. If the resource could not be found empty string is * returned */ public static String getValue(String key) { return getValue(key, ""); } /** * Will retrieve the resource bundle value given the key in the form of class.key. * * @param key * In the form of CLASS.KEY. For example, * "com.ptc.windchill.enterprise.folder.folderResource.PARTS_VIEW". * @param def * The default value you want in the case that the locale could not be looked up. * @return The value returned from the resource bundle lookup. */ public static String getValue(String key, String def) { String value = getInstance().getValueFromServer(key); return (value == null) ? def : value; } /** * Gets the localized string, unescapes the quot and puts the inserts in. * * @param key * In the form of CLASS.KEY. For example, * "com.ptc.windchill.enterprise.folder.folderResource.PARTS_VIEW". * @param inserts * A list of inserts in order of the numbering in the rbinfo file. * @return The final string. */ public static String getValue(String key, List<String> inserts) { String value = getInstance().getValueFromServer(key); for (int i = 0; i < inserts.size(); i++) { value = value.replace("{" + i + "}", inserts.get(i)); } value = value.replaceAll(""", """); return value; } private String getValueFromServer(String key) { InputStream ins = null; try { log.debug("Using Session Cookie = " + this.cookie); URL url = new URL(this.baseURL + "/netmarkets/jsp/util/getBundleKey.jsp?key=" + key); URLConnection conn = url.openConnection(); conn.setRequestProperty("Cookie", "JSESSIONID=" + this.cookie); conn.setRequestProperty("Accept-Language", this.locale); conn.setRequestProperty("Authorization", "Basic " + encode(this.username + ":" + this.password)); String value = null; try { ins = conn.getInputStream(); BufferedReader reader = new BufferedReader(new InputStreamReader(ins)); value = reader.readLine(); log.debug("Fetched RbInfo Key=" + key + " Value=" + value); } finally { if (ins != null) { ins.close(); } } return value; } catch (Exception e) { throw new RuntimeException("Unable to reach server.", e); } } /** * Encode the string for use in the header. * * @param source * The string you want to encode using base 64 encoding. * @return The encoded string. */ public static String encode(String source) { BASE64Encoder enc = new sun.misc.BASE64Encoder(); return (enc.encode(source.getBytes())); } } |
Ryan,
Sorry for my English, I’m French.
I’m very interested in your work since it seems to be close from what I’m doing.
I’m working in a French aerospace company and I use selenium webdriver in order to pull a bunch of information from PDMLink .
It’s working not too bad but not as good as it should.
Some of the pages are so big that they simply can’t be shown.
I don’t think using webdriver is the state of the art way of pulling information from PDMLink.
Do you know if there is a way to request data from PDMLink in a different format, json for example?
Many thanks for any answer.
Fabrice.
Fabrice,
Good afternoon! You can pull information from PDMLink in many different ways. Depends on what version of PDMLink you have installed. Some information is available as JSON but that is in the newest version. I am guessing you are pulling information off of tables on the page? If so, there is an export option that you can use (for instance on the folder browser). The export option supports XML, Excel, HTML, and plain text. There is also the ability to use Info*Engine or the query builder. These would give you faster performance for pulling data.
Not sure if that helps or not.
– Ryan