Reading text using selenium webdriver(xpath) - xpath

I'm using selenium to get some text on my webpage using xpath.
The page tag structure is as follows -
<span id="data" class="firefinder-match">
Seat Height, Laden
<sup>
<a class="speckeyfootnote" rel="p7" href="#">7</a>
</sup>
</span>
If I use the following code -
driver.findElement(By.xpath("//span[#id='data']")).getText();
I get the result = Seat Height, Laden 7
But I want to avoid reading the text within the <sup> tags and get the
result Seat Height, Laden
Please let me know which xpath expression I can use to get my desired result.

I don't know about any way to do this in Selenium, so there's my JS solution. The idea is to get all children of the element (including the text nodes) and then select only the text nodes. You might need to add some .trim() (or JS equivalent) calls to get rid of unneeded spaces.
The whole code:
WebElement elem = driver.findElement(By.id("data"));
String text;
if (driver instanceof JavascriptExecutor) {
text = ((JavascriptExecutor)driver).executeScript(
"var nodes = arguments[0].childNodes;" +
"var text = '';" +
"for (var i = 0; i < nodes.length; i++) {" +
" if (nodes[i].nodeType == Node.TEXT_NODE) {" +
" text += nodes[i].textContent;" +
" }" +
"}" +
"return text;"
, elem);
}
And just the JS for better readability.
var nodes = arguments[0].childNodes;
var text = '';
for (var i = 0; i < nodes.length; i++) {
if (nodes[i].nodeType == Node.TEXT_NODE) {
text += nodes[i].textContent;
}
}
return text;

Related

How can I generate an EAN 13 barcode shorter in length?

I generated an EAN 13 barcode by using IDAutomationHC39M font. I found this barcode I generated is so long in width,so each bar is so thin. However, I found somebody's EAN 13 barcode is shorter in length and each bar got more density. How can I achieve the same result? Thanks.
Pictures would help us understand what you are trying to do.
EAN 13 does not use the code 39 symbology, which is what IDAutomationHC39M produces. Instead EAN 13 uses a binary encoding scheme similar to the UPC symbol that encodes a series of bars and spaces that depends on the position in the symbol and the number being represented.
It's one of the more complex symbologies. You can utilize the following code to create your own EAN 13 with client-side JavaScript.
// The MIT License (MIT)
// Copyright (c) 2017, Notionovus, LLC.
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
// Generic arrays for drawing 5-bit graphics. Building blocks for all barcode symbologies
// Painstakingly derived gobblety-goop, but essentially the two middle sections of image data unique to each graphic
var array5bit_A = new Array ( 'f//AAAAAAAAAAAAAAAAAAAA', 'f//AAAAAAAAAAAAAAAAAAAB', 'f//AAAAAAAAAAAAAAEAAAD/',
'f//AAAAAAAAAAAAAAEAAAAA', 'f//AAAAAAAAAQAAAP8AAAAA', 'f//AAAAAAAAAQAAAP8AAAAB', 'f//AAAAAAAAAQAAAAAAAAD/',
'f//AAAAAAAAAQAAAAAAAAAA', 'f//AAABAAAA/wAAAAAAAAAA', 'f//AAABAAAA/wAAAAAAAAAB', 'f//AAABAAAA/wAAAAEAAAD/',
'f//AAABAAAA/wAAAAEAAAAA', 'f//AAABAAAAAAAAAP8AAAAA', 'f//AAABAAAAAAAAAP8AAAAB', 'f//AAABAAAAAAAAAAAAAAD/',
'f//AAABAAAAAAAAAAAAAAAA', 'QD/AAD/AAAAAAAAAAAAAAAA', 'QD/AAD/AAAAAAAAAAAAAAAB', 'QD/AAD/AAAAAAAAAAEAAAD/',
'QD/AAD/AAAAAAAAAAEAAAAA', 'QD/AAD/AAAAAQAAAP8AAAAA', 'QD/AAD/AAAAAQAAAP8AAAAB', 'QD/AAD/AAAAAQAAAAAAAAD/',
'QD/AAD/AAAAAQAAAAAAAAAA', 'QD/AAAAAAAA/wAAAAAAAAAA', 'QD/AAAAAAAA/wAAAAAAAAAB', 'SL/AADeAAAA/gAAAAIAAAD+',
'QD/AAAAAAAA/wAAAAEAAAAA', 'QD/AAAAAAAAAAAAAP8AAAAA', 'QD/AAAAAAAAAAAAAP8AAAAB', 'QD/AAAAAAAAAAAAAAAAAAD/',
'QD/AAAAAAAAAAAAAAAAAAAA');
var array5bit_B = new Array ( 'US0CAuSD38g', 'UUYCA7QBErs', 'ajEDAm49ReY', 'UUoCA+juogg', 'bjEDAjQrOn0', 'bkoDA3iPVH4',
'ajUDAt82atY', 'UU4CA1nljTg', 'cjEDAghkmFU', 'ckoDA0TA9lY', 'izUEAhrxcbg', 'ck4DAxY8F10', 'bjUDAlvFFR8', 'bk4DAxdhexw',
'ajkDAr7LFAw', 'UVICAyQ+UJI', 'TTECAq7UnEM', 'TUoCA+Jw8kA', 'ZjUDAmZGozo', 'TU4CA7CME0s', 'ajUDAvnk9E4', 'ak4DA7VAmk0',
'ZjkDAtle3bI', 'TVICAxOyzrM', 'STUCAqHeHtM', 'SU4CA+16cNA', 'h6QEAZKdo54', 'SVICA62zYxM', 'RTkCAqx1lb4', 'RVICA/z3WM0',
'QT0CAkdoxRU', 'KFYBA46vJCA');
// Painstakingly derived gobblety-goop, but essentially the front, back and mid-matter common to all barcode images...
var stringStart = '<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAACCAQAAADLaIVbAAAANUlEQVQIHQEqANX/A';
var stringMid = 'AAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAA';
var stringEnd = 'AAAAASUVORK5CYII=" width="';
function genBarcode(inputString,intWidth,intHeight) { // Input is a long string of 1's and 0's, output is the HTML <img> stack
// Pads to the last character to ensure length is divisible by 5
var intRawmod = inputString.length % 5; // Modulo 5 remainder
if (intRawmod > 0) for (var i = 0; i < 5 - intRawmod; i++) inputString += "0"; // If not evenly divisible, pad with zeroes
var arraySeq = new Array (intChunks = inputString.length / 5); // Create array for as many chunks as are now in input string
for (var i = 0; i < intChunks; i++) arraySeq[i] = parseInt(inputString.substr(i * 5, 5), 2); // Converts string of 1's and 0's to integer array
// Takes integer array and converts to "<img ...>" graphics for display
var resultString = "";
for (var i = 0; i < arraySeq.length; i++) {
resultString += stringStart + array5bit_A[arraySeq[i]] + stringMid + array5bit_B[arraySeq[i]] + stringEnd + intWidth + '" height="' + intHeight + '">';
}
return resultString;
}
///////////////////////////////////////////
// Symbology-specific arrays
// UPC Specific Arrays
var arrayCodeEANBin, arrayStructEAN;
arrayCodeEANBin = [ [ '0001101', '0011001', '0010011', '0111101', '0100011', '0110001', '0101111', '0111011', '0110111', '0001011' ], [ '0100111', '0110011', '0011011', '0100001', '0011101', '0111001', '0000101', '0010001', '0001001', '0010111' ], [ '1110010', '1100110', '1101100', '1000010', '1011100', '1001110', '1010000', '1000100', '1001000', '1110100' ] ];
arrayStructEAN = ['000000', '001011', '001101', '001110', '010011', '011001', '011100', '010101', '010110', '011010'];
///////////////////////////////////////////
// Global Variables
var strRaw = "";
var strText = "";
///////////////////////////////////////////
// Symbology-specific functions
function funcEAN() { // EAN-13
var intSumOdd = 0, intSumEven = 0, intCheck, i, j, strStruct;
// Compute check digit and add it to raw string
for (i = 0; i < 12; i += 2) {
intSumEven += parseInt(strText[i]);
intSumOdd += parseInt(strText[i+1]);
}
intCheck = ((intSumOdd * 3) + intSumEven) % 10;
if (intCheck > 0) {
intCheck = 10 - intCheck;
}
strText += intCheck;
// Converts Code EAN array into string of 1's and 0's
strRaw = "101";
// First six bar sequences
strStruct = arrayStructEAN[strText[0]];
for (i = 1; i < 7; i += 1) {
strRaw += arrayCodeEANBin[strStruct[i-1]][strText[i]];
}
// Middle sequence
strRaw += "01010";
// Last six bar sequences, including check digit
for (i = 0; i < 6; i += 1) {
strRaw += arrayCodeEANBin[2][strText[i+7]];
}
strRaw += "101";
} // End EAN-13
var buttonBarcode = document.getElementById("btnGenBar");
buttonBarcode.onclick = function () {
var intHt = intWd = 0;
var strImages = "";
document.getElementById("textImages").value = strImages;
intWd = document.getElementById("textWidth").value;
intHt = document.getElementById("textHeight").value;
strText = document.getElementById("textBarcode").value;
funcEAN();
document.getElementById("result").innerHTML = strImages = genBarcode(strRaw,intWd,intHt);
document.getElementById("textImages").value = strImages;
document.getElementById("textRaw").value = strRaw;
document.getElementById("textImages").select();
}
<head>
<title>EAN-13 Barcodes in vanilla JavaScript</title>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
</head>
<body>
<h1>EAN-13 Barcodes written in vanilla JavaScript</h1>
<h4>Enter text (a 12-digit number), enter a non-ridiculous height in pixels, enter a width between 4 (so small) and 40 (gigantor) and press the button. Magic will ensue. Print page or copy HTML out of box and paste it where it will do some good.</h4>
<div id="inputForm">
Enter Text: <input type="text" id="textBarcode" placeholder="12 Digit Number" tabindex=1/>
Height: <input type="text" id="textHeight" size="3" placeholder="40-100" maxlength="5" tabindex=2/>
Width: <input type="text" id="textWidth" size="3" placeholder="4.0-40.9" maxlength="5" tabindex=3/>
<input type="button" id="btnGenBar" value="Generate Barcode" tabindex=4/>
</div>
<p></p>
<div id="result"></div>
<p></p>
<textarea rows="30" cols="110" id="textImages" tabindex=0></textarea>
<p></p>
<textarea rows="3" cols="110" id="textRaw" tabindex=0></textarea>
<script type="text/javascript" src="./JS-EAN-13.js"></script>
</body>
</html>

InDesign Endnote Automation

I'm using this simple script to grab text wrapped in [ENDNOTE][/ENDNOTE] tags and make them into actual InDesign endnotes. The problem I'm having is that only the first 4 characters are being placed between the endnote markers (see screenshot below), any idea why this is happening, or how to make it work right?
var doc = app.activeDocument;
function footnoteToEndnotes () {
app.findGrepPreferences = null;
app.findGrepPreferences.findWhat = '\\[ENDNOTE\\](.+?)\\[\\/ENDNOTE\\]';
var endnote,
fnotes = doc.findGrep();
for (var i = fnotes.length-1; i >= 0; i--) {
var taggedText = fnotes[i].contents.replace('[ENDNOTE]', '').replace('[/ENDNOTE]', '');
endnote = fnotes[i].insertionPoints[0].createEndnote();
endnote.texts[0].contents = taggedText;
fnotes[i].remove();
}
}
if (parseInt (app.version) < 13) {
alert ('This script requires InDesign CC2018 or later');
exit();
}
doc.endnoteOptions.frameCreateOption = EndnoteFrameCreate.NEW_PAGE;
footnoteToEndnotes();
So, when I set the content of insertionPoints[0], the full endnote ended up inside the endnote markers. But, there was an extraneous tab character at the end of the string... I stripped it out and it's working like I want!
I replaced this line:
endnote.texts[0].contents = taggedText;
With these:
endnote.texts[0].insertionPoints[0].contents = taggedText;
endnote.texts[0].contents = endnote.texts[0].contents.replace('\t', '');

Javascript generating anchors quote issue

I'm new to this site and new to Javascript, however I'm been coding in C for some years, and I ran into a problem that totally blows my mind.
I want to make a tool for myself (a very simple code generating tool). I want to generate html code and in a displayable manner, because the final product would be a static page (no javascript). So I tried to solve it with basic string manipulation.
The task and the code is so simple I'll just post it here.
Javascript with it's corresponding tags:
<script>
function ConvertListToGallery()
{
var cont = document.getElementById("gallery_generator_input");
var eof_link;
var eof_title;
var eof_descr;
var lines = [];
var tokens = [];
var i, k;
var result = document.getElementById("gallery_generator_output");
var link;
var lofasz = [];
if(cont)
{
lines = cont.value.split('\n');
lofasz = cont.value.split('"');
console.log(lofasz[0]);
result.innerHTML = "";
for( i = 0; i < lines.length; i++ )
{
tokens = lines[i].split(" + ");
for( k = 0; k < tokens.length; k++ )
{ console.log(tokens[k]); }
link = tokens[0];
result.innerHTML += '<img src=' + link + '/>';
}
document.getElementById("gallery_generator_result").value=result.innerHTML;
document.getElementById("gallery_convert").innerHTML = "Done!";
document.getElementById("gallery_convert").onclick = "";
}
}
</script>
The input:
https://drive.google.com/uc?id=0B3ju3vX1o4OuY0RaaDJKWnlRN1U + title +
desc https://drive.google.com/uc?id=0B3ju3vX1o4OuSC1hNFQwUV9IWlE +
title2 + desc2
And the output after running the script:
<img src="https://drive.google.com/uc?id=0B3ju3vX1o4OuY0RaaDJKWnlRN1U/"><img src="https://drive.google.com/uc?id=0B3ju3vX1o4OuSC1hNFQwUV9IWlE/">
It's like something automatically put quotes around the links. Sorry, I have tried so many things I can't remember now, but as I remember this "auto-quoting" thing only happens with links and it causes all sorts of problem in the resulting code (for example the '/' slips inside the quotes). And all other problems were caused by this behavior (I can't assign title and other attributes inside the img tag).
Additional html:
<form>
<textarea id="gallery_generator_input" style = "width:800px;"></textarea></form>
<div id="gallery_generator_output" style="border:solid; max-height:500px; overflow:auto;">
</div>
<textarea id="gallery_generator_result" style = "width:800px;"></textarea>
<div onclick = "ConvertListToGallery();" id="gallery_convert">Convert!</div>
Thank you for any hints in advance!
EDIT: removed the misleading WOW thing.
The desired result is simply a valid html image code.
Change this line
result.innerHTML += '<img src=' + link + '!!WOW>';
to this
result.innerHTML += '<img src="' + link + '!!WOW"/>';
also you can urlencode the exclamation marks if they are a problem:
result.innerHTML += '<img src="' + link + '%21%21WOW"/>';
Sorry for the late follow-up, but it turned out that writing to the innerHMTL caused the issue (I'm still not sure if writing to innerHTML has some kind of obscure code fixing/completion feature). If I accumulate the HTML in a separate variable THEN assign it to the innerHTML has no issues.
I know that it's not the best practice to make dynamic code like that (the elements don't get added to the DOM tree), but for my use it's simpler to make the code this way, since it's only a tool for me to generate static pages.

How to get the XPath of a grid cell using Firebug?

I am working on a UI. My job is to automate it. I came across the following grid.
When you click on any cell under the Rule column, a browse button appears.
I am supposed to automate this scenario. So, using Firebug I am trying to extract the XPath of that cell.
I used Firebug's inspector to locate that particular cell, so that I can write the XPath for it, but I am unable to locate that cell. Instead, the entire row is getting selected, as shown in next images.
How should I approach this problem?
below code might help you to verify the grid values,
public void verifyTableValues(String expectedValue
) {
try {
//List of Fields values which you want to verify
List<String> expectedValues = Arrays.asList(expectedValue.split("#"));
// you will get the number of rows in Table Select the xpath to /tr
String tableRow = driver.findElements(By.xpath(//table row constant));
int tableRwCnt = getCount(tableRow);
// you will get the number of Columns in Table Select the xpath to /td
String tableColumn = driver.findElements(By.xpath(//table Column constant));
int tableColumnCnt = getCount(tableColumn);
for (int cnt = 1; cnt <= tableRwCnt; cnt++) {
for (int listCount = 1; listCount <= tableColumnCnt; listCount++) {
String actualVal = findElement(By.xpath(tableColumn + "[" + cnt + "]/td["
+ expectedValues.get(listCount) + "]").getText();
String expectdVal = expectedValues.get(listCount);
Assert.assertEquals("Value from table doent Match", expectdVal, actualVal);
}
}
} catch (Exception e) {
// code for exception
}
}
Parameter: expectedValue = test1#test2#test4#test4 (Grid values)

How to replace selected text in InDesign via script?

In my scripted UI panel, I have a button that is supposed to insert some text. I came up with this routine, which, indeed, inserts whatever text wherever I want, but if there is any text already selected, it doesn't replace the selection.
How can I modify this function to replace the selection? If there is nothing selected, it should just insert the text normally.
function insertText(whattext){
if( app.selection.length < 1 ){ exit(); }
var tf = app.selection;
for( var q = 0; q < tf.length; q++ ){
var thisframe = tf[q];
var originaltext = thisframe.contents;
thisframe.contents = originaltext + whattext;
}
}
Hmmm... well, this seems to work pretty well... [embarassed look on face]
function insertText(whattext){
app.selection[0].contents = whattext;
}

Resources