How can we access the actual element in Selenium-webdriver (Java)? - gwt

In selenium-webdriver (Java),
We can get the GWT element
for eg. WebElement obj = driver.findElement(By.id("gwt-debug-celltable"));
By obj we can get that webelement of the celltable but we won't get the actual celltable. So if want to check the number of records in the celltable using Selenium-Webdriver. What i need to do?
Is it possible? If yes please answer asap.

Yes. You can do it using xpath, somehow:
List<WebElement> elements =
driver.findElements(By.xpath("//table[#id='gwt-debug-celltable']/tbody/tr"));
In elements will be the list of rows. I have not tested this code. But it likes one that we are using in our project.

For the webtable i have refered the below link http://money.rediff.com/gainers/bsc/daily/groupa
from the below code you can get all the values from the webtable
public class MaxFromTable {
public static void main(String[] args) throws ParseException {
WebDriver wd;
System.setProperty("webdriver.chrome.driver","G://chromedriver.exe");
wd= new ChromeDriver();
wd.get("http://money.rediff.com/gainers/bsc/daily/groupa?");
String max;
double m=0,r=0;
//No. of Columns
List col = wd.findElements(By.xpath(".//[#id='leftcontainer']/table/thead/tr/th"));
System.out.println("Total No of columns are : " +col.size());
//No.of rows
List rows = wd.findElements(By.xpath (".//*[#id='leftcontainer']/table/tbody/tr/td[1]"));
System.out.println("Total No of rows are : " + rows.size());
for (int i =1;i<rows.size();i++)
{
max= wd.findElement(By.xpath("html/body/div[1]/div[5]/table/tbody/tr[" + (i+1)+ "]/td[4]")).getText();
NumberFormat f =NumberFormat.getNumberInstance();
Number num = f.parse(max);
max = num.toString();
m = Double.parseDouble(max);
if(m>r)
{
r=m;
}
}
System.out.println("Maximum current price is : "+ r);
}
}

Related

How do I export AEM reports in Excel?

I'd like to to export AEM reports, page activity or component activity reports, in an excel file.
Is this feature is available in AEM or do I have to write custom for this?
The closest you will get is a CSV selector that can convert report data to CSV but even that has limitations (pagination, filters may be ignored depending on the report).
This, AFAIK, is not an OOTB function. There are old posts and blogs out there to show how this can be done on bpth client side (using JS) or server side using CSV writers.
If you are going down the route of writing a custom solution (most likely outcoume), have a look at the CSV text library that is used in acs-commons user CSV import/export utility, that makes the job really easy and is already a part of AEM.
Hope this helps.
The WriteExcel class simply takes the List collection that is used to populate the JTable object and writes the data to an Excel spreadsheet.
This class uses the Java Excel API. The Java Excel API dependency that is required to work with this API is already in the POM dependencies section.
import java.io.File;
import java.io.IOException;
import java.util.List;
import java.util.Locale;
import jxl.CellView;
import jxl.Workbook;
import jxl.WorkbookSettings;
import jxl.format.UnderlineStyle;
import jxl.write.Formula;
import jxl.write.Label;
import jxl.write.Number;
import jxl.write.WritableCellFormat;
import jxl.write.WritableFont;
import jxl.write.WritableSheet;
import jxl.write.WritableWorkbook;
import jxl.write.WriteException;
import jxl.write.biff.RowsExceededException;
public class WriteExcel {
private WritableCellFormat timesBoldUnderline;
private WritableCellFormat times;
private String inputFile;
public void setOutputFile(String inputFile) {
this.inputFile = inputFile;
}
public int write( List<members> memberList) throws IOException, WriteException {
File file = new File(inputFile);
WorkbookSettings wbSettings = new WorkbookSettings();
wbSettings.setLocale(new Locale("en", "EN"));
WritableWorkbook workbook = Workbook.createWorkbook(file, wbSettings);
workbook.createSheet("Comumunity Report", 0);
WritableSheet excelSheet = workbook.getSheet(0);
createLabel(excelSheet) ;
int size = createContent(excelSheet, memberList);
workbook.write();
workbook.close();
return size ;
}
private void createLabel(WritableSheet sheet)
throws WriteException {
// Lets create a times font
WritableFont times10pt = new WritableFont(WritableFont.TIMES, 10);
// Define the cell format
times = new WritableCellFormat(times10pt);
// Lets automatically wrap the cells
times.setWrap(true);
// create create a bold font with unterlines
WritableFont times10ptBoldUnderline = new WritableFont(WritableFont.TIMES, 10, WritableFont.BOLD, false,
UnderlineStyle.SINGLE);
timesBoldUnderline = new WritableCellFormat(times10ptBoldUnderline);
// Lets automatically wrap the cells
timesBoldUnderline.setWrap(true);
CellView cv = new CellView();
cv.setFormat(times);
cv.setFormat(timesBoldUnderline);
cv.setAutosize(true);
// Write a few headers
addCaption(sheet, 0, 0, "Number");
addCaption(sheet, 1, 0, "Points");
addCaption(sheet, 2, 0, "Name");
addCaption(sheet, 3, 0, "Screen Name");
}
private int createContent(WritableSheet sheet, List<members> memberList) throws WriteException,
RowsExceededException {
int size = memberList.size() ;
// This is where we will add Data from the JCR
for (int i = 0; i < size; i++) {
members mem = (members)memberList.get(i) ;
String number = mem.getNum();
String points = mem.getScore();
String name = mem.getName();
String display = mem.getDisplay();
// First column
addLabel(sheet, 0, i+2, number);
// Second column
addLabel(sheet, 1, i+2, points);
// Second column
addLabel(sheet, 2, i+2,name);
// Second column
addLabel(sheet, 3, i+2, display);
}
return size;
}
private void addCaption(WritableSheet sheet, int column, int row, String s)
throws RowsExceededException, WriteException {
Label label;
label = new Label(column, row, s, timesBoldUnderline);
sheet.addCell(label);
}
private void addNumber(WritableSheet sheet, int column, int row,
Integer integer) throws WriteException, RowsExceededException {
Number number;
number = new Number(column, row, integer, times);
sheet.addCell(number);
}
private void addLabel(WritableSheet sheet, int column, int row, String s)
throws WriteException, RowsExceededException {
Label label;
label = new Label(column, row, s, times);
sheet.addCell(label);
}
public int exportExcel( List<members> memberList)
{
try
{
setOutputFile("JCRMembers.xls");
int recs = write( memberList);
return recs ;
}
catch(Exception e)
{
e.printStackTrace();
}
return -1;
}
}
You can follow the steps described here: Adobe Forums
Select your required page to see component report at http://localhost:4502/etc/reports/compreport.html
Now hit the below URL. It gives you JSON output. http://localhost:4502/etc/reports/compreport/jcr:content/report.data.json
Copy paste the generated JSON output at below URL and click on JSON to excel http://www.convertcsv.com/json-to-csv.htm
You need to write your own logic
create a servlet,
construct Table with data
in the response object add below lines
response.setContentType("text/csv");
response.setCharacterEncoding("UTF-8");
response.setHeader("Content-Disposition", "attachment; filename=\"" + reportName + ".csv\"");
Cookie cookie = new Cookie("fileDownload", "true");
cookie.setMaxAge(-1);
cookie.setPath("/");
response.addCookie(cookie);
once click on the button you will get the report in the Excel format.

How to handle autocomplete list in webdriver?

How to select country name from auto-complete drop down list?
Please provide suggestion with code for Google search so that i can understand.
If your dropdown is editable you can directly type the values using send keys, else you need to simulate the Arrow down key actions as you needed. But it not wise once, because if new values are added in the drop down(Anyway in this case, there will be fixed because the number of countries is a constant),then it will get messed.
driver.findElement(locator).sendKeys(countryName , Keys.TAB);
or
driver.findElement(locator).sendKeys(Keys.DOWN);
Try the following code:
WebElement dropdown = driver.findElement(By.....);
Select dropdownSelect = new Select(dropdown);
dropdownSelect.selectByVisibleText(itemStr) or selectByValue(value);
Link : http://www.mythoughts.co.in/2012/05/getting-google-search-auto-suggestions.html#.Ul-lJdi1Zbc
#Test
public void SearchSuggestion() {
driver.get("http://google.com");
driver.findElement(By.id("gbqfq")).sendKeys("vam");
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
WebElement table = driver.findElement(By.className("gssb_m"));
List<webelement> rows = table.findElements(By.tagName("tr"));
Iterator<webelement> i = rows.iterator();
System.out.println("-----------------------------------------");
while(i.hasNext()) {
WebElement row = i.next();
List<webelement> columns = row.findElements(By.tagName("td"));
Iterator<webelement> j = columns.iterator();
while(j.hasNext()) {
WebElement column = j.next();
System.out.println(column.getText());
}
System.out.println("");
System.out.println("-----------------------------------------");
}
}
}
driver.findElement(By.id("your searchBox")).sendKeys("your partial keyword");
Thread.sleep(3000);
List <WebElement> listItems = driver.findElements(By.xpath("your list item locator"));
listItems.get(0).click();
driver.findElement(By.id("your searchButton")).click()

GWT filler rows in a CellTable

I currently have a CellTable which I expanded with a filter/paging/sorting.
I am working on adding more features too.
One things that bugs me though, is when you set the limit for a page to be for example 10.
If an object doesn't have 10 rows and only has 5 and you switch between them then the table will jump up and down if positioned in the center.
Is there an elegant way, that when the pageSize is set to 10, then if there are less than 10 rows in a table, empty rows will be added?
The ways I have tried so far effect my filtering/sorting/paging, which I do not want.
EDIT 1:
final AsyncDataProvider<Row> provider = new AsyncDataProvider<Row>() {
#Override
protected void onRangeChanged(HasData<Row> display) {
int start = display.getVisibleRange().getStart();
int end = start + display.getVisibleRange().getLength();
end = end >= rows.getFilterList().size() ? rows.getFilterList().size() : end;
List<Row> sub = rows.getFilterList().subList(start, end);
System.out.println("Checking if extra rows needed: " +
table.getVisibleItems().size());
for(int i = table.getVisibleItems().size(); i<10; i++){
System.out.println("ADDED EMPTY ROW");
sub.add(new Row());
}
updateRowData(start, sub);
}
};
I had the same problem. I solved it by adding null rows. Basically, you need to override onRangeChange(HasData<T> display) in your DataProvider to add null to the list representing the range asked for. You add enough null to fill the range you want.
#Override
protected void onRangeChanged(HasData<T> display){
Range range = display.getVisibleRange();
List<T> listOfObjects = getRange(range);
for(int i=listOfObject.size(); i<range.getLength(); i++){
listOfObjects.add(null);
}
updateRowData(range.getStart(), listofObjects);
}
In the above code getRange() returns a list containing the objects that are requested (within the range)
You'll also have to add some CSS to give a height to rows. If you don't specify the height then the rows will be very small so they won't pad the whole table.
It's disappointing that GWT doesn't have support for this type of padding. This way was the best one that I found but unfortunately when your row heights differ within a table it makes everything harder.
Paging
With the solution above you'll need to have a custom Pager if you want paging. You can extend your AsyncDataProvider with method like getVisibleRowCount() this will return how many objects in the current sublist are actually real data (not null). Then you can give a reference of the AsyncDataProvider to the Pager and override the createText() method:
#Override
protected String createText(){
return getPageStart() + " - " + dataProvider.getVisibileRowCount() + " of "
+ dataProvider.getTotalRowCount();
}

How to filter datagridview using text inputted from a rich text box?

I have a datagridview that I want to display a data from a database. But I don't want it to display all of the data. I want it to display the data for a specific ID only. Meaning if the user enters 3 ID, it will display the info for that 3 ID. Hence I want to use a rich text box as a filter so that the user can enter multiple ID for each line in the rich text box. The user can enter the ID No. within the rich text box and the data will be used as a filter to display the data for that particular ID. But I cannot make it read beyond the first line of the rich text box. If I enter just one ID in the first line, it works perfectly, but if I enter a second ID in the second line, or in the third line, then it will not display anything at all. I tried using for loop to read each line of the rich text box but it doesn't work. Any advice or solution??
here is my code :
namespace TrackCon
{
public partial class trackInput : Form
{
public trackInput()
{
InitializeComponent();
}
/*private void trackInput_Load(object sender, EventArgs e)
{
// TODO: This line of code loads data into the 'trackingBMSDATADataSet.BRDATA' table. You can move, or remove it, as needed.
this.bRDATATableAdapter.Fill(this.trackingBMSDATADataSet.BRDATA);
}*/
private void trackBtn_Click(object sender, EventArgs e)
{
RichTextBox dynamicRichTextBox = new RichTextBox();
DataTable dt = null;
string connoInput = richTextBox1.Text;
string conString = Properties.Settings.Default.BMSDATAConnectionString;
//string[] RichTextBoxLines = dynamicRichTextBox.Lines;
foreach (char line in richTextBox1.Text)
{
using (SqlCeConnection con = new SqlCeConnection(#"Data Source=C:\Documents and Settings\Administrator\My Documents\Visual Studio 2008\Projects\TrackCon\TrackCon\BMSDATA.sdf;Persist Security Info = True;Password=xxxx"))
{
con.Open();
SqlCeCommand com = new SqlCeCommand("SELECT conno,cmpsno,ctrx,dsysdate,cstnno,corigin FROM BRDATA WHERE conno = '" + richTextBox1.Text + "'OR cmpsno = '" + richTextBox1.Text + "'", con);
SqlCeDataAdapter adap = new SqlCeDataAdapter(com);
DataSet set = new DataSet();
adap.Fill(set);
if (set.Tables.Count > 0)
{
dt = set.Tables[0];
}
dataGridView1.DataSource = dt;
con.Close();
}
}
}
}
}
I suggest to use a TextBox and set MultiLine to true.
Then you can read all the ids like this:
string[] ids = myTextBox.Text.Split('\n');
EDIT:
You can use SQL's IN to find all elements:
string sql = "SELECT conno, etc FROM BRDATA WHERE conno IN (" + String.Join(", ", ids) + ")";

using the TSqlParser

I'm attempting to parse SQL using the TSql100Parser provided by microsoft. Right now I'm having a little trouble using it the way it seems to be intended to be used. Also, the lack of documentation doesn't help. (example: http://msdn.microsoft.com/en-us/library/microsoft.data.schema.scriptdom.sql.tsql100parser.aspx )
When I run a simple SELECT statement through the parser it returns a collection of TSqlStatements which contains a SELECT statement.
Trouble is, the TSqlSelect statement doesn't contain attributes such as a WHERE clause, even though the clause is implemented as a class. http://msdn.microsoft.com/en-us/library/microsoft.data.schema.scriptdom.sql.whereclause.aspx
The parser does recognise the WHERE clause as such, looking at the token stream.
So, my question is, am I using the parser correctly? Right now the token stream seems to be the most useful feature of the parser...
My Test project:
public static void Main(string[] args)
{
var parser = new TSql100Parser(false);
IList<ParseError> Errors;
IScriptFragment result = parser.Parse(
new StringReader("Select col from T1 where 1 = 1 group by 1;" +
"select col2 from T2;" +
"select col1 from tbl1 where id in (select id from tbl);"),
out Errors);
var Script = result as TSqlScript;
foreach (var ts in Script.Batches)
{
Console.WriteLine("new batch");
foreach (var st in ts.Statements)
{
IterateStatement(st);
}
}
}
static void IterateStatement(TSqlStatement statement)
{
Console.WriteLine("New Statement");
if (statement is SelectStatement)
{
PrintStatement(sstmnt);
}
}
Yes, you are using the parser correctly.
As Damien_The_Unbeliever points out, within the SelectStatement there is a QueryExpression property which will be a QuerySpecification object for your third select statement (with the WHERE clause).
This represents the 'real' SELECT bit of the query (whereas the outer SelectStatement object you are looking at has just got the 'WITH' clause (for CTEs), 'FOR' clause (for XML), 'ORDER BY' and other bits)
The QuerySpecification object is the object with the FromClauses, WhereClause, GroupByClause etc.
So you can get to your WHERE Clause by using:
((QuerySpecification)((SelectStatement)statement).QueryExpression).WhereClause
which has a SearchCondition property etc. etc.
Quick glance around would indicate that it contains a QueryExpression, which could be a QuerySpecification, which does have the Where clause attached to it.
if someone lands here and wants to know how to get the whole elements of a select statement the following code explain that:
QuerySpecification spec = (QuerySpecification)(((SelectStatement)st).QueryExpression);
StringBuilder sb = new StringBuilder();
sb.AppendLine("Select Elements");
foreach (var elm in spec.SelectElements)
sb.Append(((Identifier)((Column)((SelectColumn)elm).Expression).Identifiers[0]).Value);
sb.AppendLine();
sb.AppendLine("From Elements");
foreach (var elm in spec.FromClauses)
sb.Append(((SchemaObjectTableSource)elm).SchemaObject.BaseIdentifier.Value);
sb.AppendLine();
sb.AppendLine("Where Elements");
BinaryExpression binaryexp = (BinaryExpression)spec.WhereClause.SearchCondition;
sb.Append("operator is " + binaryexp.BinaryExpressionType);
if (binaryexp.FirstExpression is Column)
sb.Append(" First exp is " + ((Identifier)((Column)binaryexp.FirstExpression).Identifiers[0]).Value);
if (binaryexp.SecondExpression is Literal)
sb.Append(" Second exp is " + ((Literal)binaryexp.SecondExpression).Value);
I had to split a SELECT statement into pieces. My goal was to COUNT how many record a query will return. My first solution was to build a sub query such as
SELECT COUNT(*) FROM (select id, name from T where cat='A' order by id) as QUERY
The problem was that in this case the order clause raises the error "The ORDER BY clause is not valid in views, inline functions, derived tables, sub-queries, and common table expressions, unless TOP or FOR XML is also specified"
So I built a parser that split a SELECT statment into fragments using the TSql100Parser class.
using Microsoft.Data.Schema.ScriptDom.Sql;
using Microsoft.Data.Schema.ScriptDom;
using System.IO;
...
public class SelectParser
{
public string Parse(string sqlSelect, out string fields, out string from, out string groupby, out string where, out string having, out string orderby)
{
TSql100Parser parser = new TSql100Parser(false);
TextReader rd = new StringReader(sqlSelect);
IList<ParseError> errors;
var fragments = parser.Parse(rd, out errors);
fields = string.Empty;
from = string.Empty;
groupby = string.Empty;
where = string.Empty;
orderby = string.Empty;
having = string.Empty;
if (errors.Count > 0)
{
var retMessage = string.Empty;
foreach (var error in errors)
{
retMessage += error.Identifier + " - " + error.Message + " - position: " + error.Offset + "; ";
}
return retMessage;
}
try
{
// Extract the query assuming it is a SelectStatement
var query = ((fragments as TSqlScript).Batches[0].Statements[0] as SelectStatement).QueryExpression;
// Constructs the From clause with the optional joins
from = (query as QuerySpecification).FromClauses[0].GetString();
// Extract the where clause
where = (query as QuerySpecification).WhereClause.GetString();
// Get the field list
var fieldList = new List<string>();
foreach (var f in (query as QuerySpecification).SelectElements)
fieldList.Add((f as SelectColumn).GetString());
fields = string.Join(", ", fieldList.ToArray());
// Get The group by clause
groupby = (query as QuerySpecification).GroupByClause.GetString();
// Get the having clause of the query
having = (query as QuerySpecification).HavingClause.GetString();
// Get the order by clause
orderby = ((fragments as TSqlScript).Batches[0].Statements[0] as SelectStatement).OrderByClause.GetString();
}
catch (Exception ex)
{
return ex.ToString();
}
return string.Empty;
}
}
public static class Extension
{
/// <summary>
/// Get a string representing the SQL source fragment
/// </summary>
/// <param name="statement">The SQL Statement to get the string from, can be any derived class</param>
/// <returns>The SQL that represents the object</returns>
public static string GetString(this TSqlFragment statement)
{
string s = string.Empty;
if (statement == null) return string.Empty;
for (int i = statement.FirstTokenIndex; i <= statement.LastTokenIndex; i++)
{
s += statement.ScriptTokenStream[i].Text;
}
return s;
}
}
And to use this class simply:
string fields, from, groupby, where, having, orderby;
SelectParser selectParser = new SelectParser();
var retMessage = selectParser.Parse("SELECT * FROM T where cat='A' Order by Id desc",
out fields, out from, out groupby, out where, out having, out orderby);