How to write a custom FindElement routine in Selenium? - selenium

I'm trying to figure out how to write a custom FindElement routine in Selenium 2.0 WebDriver. The idea would be something like this:
driver.FindElement(By.Method( (ISearchContext) => {
/* examine search context logic here... */ }));
The anonymous method would examine the ISearchContext and return True if it matches; False otherwise.
I'm digging through the Selenium code, and getting a bit lost. It looks like the actual By.* logic is carried out server-side, not client side. That seems to be complicating matters.
Any suggestions?

I do a multi-staged search. I have a method that performs a try catch and then a method that gets the element. In theory you could do a try catch until instead of this way but I like this way better because of my setup.
public bool CheckUntil(IWebDriver driver, string selectorType, string selectorInfo)
{
int Timer = 160;
bool itemFound = false;
for (int i = 0; i < Timer; i++)
if(itemFound)
{
i = 0
}
else
{
Thread.Sleep(500);
if(selectorType.ToLower() == "id" && TryCatch(driver, selectorType, selectorInfo))
{
if(driver.FindElement(By.Id(selectorInfo).Displayed)
{
itemFound = true;
}
}
else if(selectorType.ToLower() == "tagname" && TryCatch(driver, selectorType, selectorInfo))
{
if(driver.FindElement(By.TagName(selectorInfo).Displayed)
{
itemFound = true;
}
}
}
return itemFound;
}
Here's my try catch method you can add as many different types as you want id, cssselector, xpath, tagname, classname, etc.
public bool TryCatch(IWebDriver driver, string selectorType, string selectorInfo)
{
bool ElementFound = false;
try
{
switch(selectorType)
{
case "id":
driver.FindElement(By.Id(selectorInfo);
break;
case "tagname":
driver.FindElement(By.TagName(selectorInfo);
break;
}
ElementFound = truel
}
catch
{
ElementFound = false;
}
return ElementFound;
}

Ok, I figured out how to do this. I'm leveraging driver.ExecuteScript() to run custom js on the webdriver. It looks a bit like this:
function elementFound(elem) {
var nodeType = navigator.appName == ""Microsoft Internet
Explorer"" ? document.ELEMENT_NODE : Node.ELEMENT_NODE;
if(elem.nodeType == nodeType)
{
/* Element identification logic here */
}
else { return false; }
}
function traverseElement(elem) {
if (elementFound(elem) == true) {
return elem;
}
else {
for (var i = 0; i < elem.childNodes.length; i++) {
var ret = traverseElement(elem.childNodes[i]);
if(ret != null) { return ret; }
}
}
}
return traverseElement(document);

Related

Function Doesn't Return a value in Dart Language

I am trying to connect my app to an API and search using the API. If the search is successful and found the name, it will return Success and if not, will return Failed, but it doesn't return anything.
import 'dart:convert';
import 'package:http/http.dart' as http;
main() {
getData();
}
String linearSearch(List<dynamic> list, String x) {
for (var i = 0; i < list.length; i++){
if(x == list[i]["name"]){
return 'Success';
}
}
return 'Failed';
}
void getData() async {
List data;
var response = await
http.get("http://localhost:3000/data");
data = jsonDecode(response.body);
linearSearch(data, 'karim');
}
Your function returns String value without any additions. You just need to assign result of your function to String variable and do something with it, if needed.
Or you just could print result of the function
void getData() async {
List data;
var response = await
http.get("http://localhost:3000/data");
data = jsonDecode(response.body);
print(linearSearch(data, 'karim'));
}
Solved by editing my linearSearch function
linearSearch(List<dynamic> list, String x) {
for (var i = 0; i < list.length; i++){
if(x == list[i]["name"]){
return print('Success');
}
}
return print('Failed');
}

How can I write code to receive whole string from a device on rs232?

I want to know how to write code which receives specific string.for example, this one OK , in this I only need "OK" string.
Another string is also like OK
I have written code in keil c51 for at89s52 microcontroller which works but I need more reliable code.
I'm using interrupt for rx data from rs232 serial.
void _esp8266_getch() interrupt 4 //UART Rx.{
if(TI){
TI=0;
xmit_bit=0;
return ;
}
else
{
count=0;
do
{
while(RI==0);
rx_buff=SBUF;
if(rx_buff==rx_data1) //rx_data1 = 0X0D /CR
{
RI=0;
while(RI==0);
rx_buff=SBUF;
if(rx_buff==rx_data2) // rx_data2 = 0x0A /LF
{
RI=0;
data_in_buffer=1;
if(loop_conti==1)
{
if(rec_bit_flag==1)
{
data_in_buffer=0;
loop_conti=0;
}
}
}
}
else
{
if(data_in_buffer==1)
{
received[count]=rx_buff; //my buffer in which storing string
rec_bit_flag=1;
count++;
loop_conti=1;
RI=0;
}
else
{
loop_conti=0;
rec_bit_flag=0;
RI=0;
}
}
}
while(loop_conti==1);
}
rx_buff=0;
}
This is one is just for reference, you need develop the logic further to your needs. Moreover, design is depends on what value is received, is there any specific pattern and many more parameter. And this is not a tested code, I tried to give my idea on design, with this disclaimer here is the sample..
//Assuming you get - "OK<CR><LF>" in which <CR><LF> indicates the end of string steam
int nCount =0;
int received[2][BUF_SIZE]; //used only 2 buffers, you can use more than 2, depending on how speed
//you receive and how fast you process it
int pingpong =0;
bool bRecFlag = FALSE;
int nNofbytes = 0;
void _esp8266_getch() interrupt 4 //UART Rx.
{
if(TI){
TI=0;
xmit_bit=0;
return ;
}
if(RI) // Rx interrupt
{
received[pingpong][nCount]=SBUF;
RI =0;
if(nCount > 0)
{
// check if you receive end of stream value
if(received[pingpong][nCount-1] == 0x0D) && (received[pingpong][nCount] == 0x0A))
{
bRecFlag = TRUE;
pingpong = (pingpong == 0);
nNofbytes = nCount;
nCount = 0;
return;
}
}
nCount++;
}
return;
}
int main()
{
// other stuff
while(1)
{
// other stuff
if(bRecFlag) //String is completely received
{
buftouse = pingpong ? 0 : 1; // when pingpong is 1, buff 0 will have last complete string
// when pingpong is 0, buff 1 will have last complete string
// copy to other buffer or do action on received[buftouse][]
bRecFlag = false;
}
// other stuff
}
}

Cannot update UI with Invoke() and BeginInvoke() in C#

My main process:
public void quoteStartReceive()
{
Thread thdWrite = new Thread(new ThreadStart(DoParseGUIDisplay));
thdWrite.IsBackground = true;
thdWrite.Start();
}
My thread function:
void DoParseGUIDisplay()
{
for (int i = 0; i < 1024; i++)
{
if (myQueue.Count > 0)
{
string strOut = myQueue.Dequeue().ToString();
Tick tick = new Tick(strOut);
if (tick.m_last != "")
{
string msg = "Update Text";
if (this.textBox1.InvokeRequired)
{
this.textBox1.BeginInvoke((MethosInvoker)delegate () {this.textBox1.Text = msg; };
}
else
{
this.textBox1.Text = msg;
}
}
}
}
}
No matter I tried to use Invoke() or BeginInvoke(), I cannot update the text in textBox1.
I also tried another way:
public delegate void UpdateTextCallback(string text);
It still cannot help me to update my textBox1.
Help me to find out what stuff I missed. Thanks.
put an argument before the thread:
Application.DoEvents();
and it should be put after the m_last was updated.

Treeviews QueueDraw doesn't render current row?

I'm working with a treeview, which contains several columns, also one displaying a pixbuf, if audio is playing or paused. If the user double clicks on one row, audio playback starts and the row needs to be rerendered in order to display the pixbuf icon. I used QueueDraw for this, but that does only work, if the cursor leaves the current row. How can I update the pixbuf directly?
CODE:
protected void trvMainCuesheetRowActivated (object o, RowActivatedArgs args)
{
log.debug("trvMainCuesheetRowActivated called");
TreeIter ti = TreeIter.Zero;
this.lsCuesheetData.GetIter(out ti,args.Path);
if (this.lsCuesheetData.GetValue(ti,0) != null)
{
Track tCurTrack = (Track)this.lsCuesheetData.GetValue(ti,0);
if (this.objProgram.getAudioManager().getPlayState() == AudioCuesheetEditor.AudioBackend.PlayState.Stopped)
{
this.objProgram.getAudioManager().play(tCurTrack);
this.refresh();
}
else
{
if (this.objProgram.getAudioManager().getPlayState() == AudioCuesheetEditor.AudioBackend.PlayState.Playing)
{
this.objProgram.getAudioManager().seek(tCurTrack);
this.refresh();
}
}
}
}
private void renderPlaying(TreeViewColumn _tvcColumn, CellRenderer _crCell, TreeModel _tmModel, TreeIter _tiIter)
{
Track tCurTrack = (Track)_tmModel.GetValue (_tiIter, 0);
//Just display an icon, if we are playing
if (this.objProgram.getAudioManager().getPlayState() == AudioCuesheetEditor.AudioBackend.PlayState.Playing)
{
if (this.objProgram.getAudioManager().getCurrentlyPlayingTrack() == tCurTrack)
{
Gdk.Pixbuf icon = this.RenderIcon(Stock.MediaPlay, IconSize.SmallToolbar, null);
(_crCell as CellRendererPixbuf).Pixbuf = icon;
}
else
{
(_crCell as CellRendererPixbuf).Pixbuf = null;
}
}
else
{
if (this.objProgram.getAudioManager().getPlayState() == AudioCuesheetEditor.AudioBackend.PlayState.Paused)
{
if (this.objProgram.getAudioManager().getCurrentlyPlayingTrack() == tCurTrack)
{
Gdk.Pixbuf icon = this.RenderIcon(Stock.MediaPause, IconSize.SmallToolbar, null);
(_crCell as CellRendererPixbuf).Pixbuf = icon;
}
else
{
(_crCell as CellRendererPixbuf).Pixbuf = null;
}
}
else
{
(_crCell as CellRendererPixbuf).Pixbuf = null;
}
}
}
//Purpose: Function used to refresh the MainWindow depending on new options set.
public void refresh()
{
//QueueDraw is needed since it fires a signal to cellrenderers to update
this.trvMainCuesheet.QueueDraw();
this.sbMainWindow.Visible = this.objProgram.getObjOption().getBShowStatusbar();
this.mwToolbar.Visible = this.objProgram.getObjOption().getBToolbarVisible();
}
Greetings
Sven
Found the error myself.
this.objProgram.getAudioManager().getCurrentlyPlayingTrack()
didn't always return a track, where I expected one, so the renderer worked right. Bug is fixed, thanks anyway ;).

Qt TableView only sorting once

I have a QTableView that is populated with a QSqlQueryModel. I am trying to sort the table based on which RadioButton is checked, but nothing is happening when I press them. There was one point where I could get it to sort, but only once. What am I doing wrong here?
void MainWindow::on_openButton_clicked()
{
QString filePath = ui->lineEdit->text();
if( filePath != "" ){
if( openDB( filePath ) ){
ui->debugLabel->setText("Database opened");
MainWindow::populateTable();
}else{
ui->debugLabel->setText("Unable to open database");
}
} else {
ui->debugLabel->setText("Path is empty");
}
}
void MainWindow::populateTable(){
if( readDB() ){
ui->tableView->setModel(toast.dbModel);
}
}
void MainWindow::on_shootButton_toggled(bool checked)
{
if( checked ){
ui->tableView->sortByColumn( 0 );
}
}
void MainWindow::on_winButton_toggled(bool checked)
{
if( checked ){
ui->tableView->sortByColumn( 1 );
}
}
bool openDB(QString path){
db = QSqlDatabase::addDatabase("QSQLITE");
db.setDatabaseName(path);
return db.open();
}
bool readDB(){
if( db.isOpen() ){
dbModel->setQuery( "select * from test", db );
return true;
} else {
return false;
}
}
QSqlQueryModel isn't sortable by default, QSqlTableModel is sortable but there's differences between the two. You can make QSqlQueryModel sortable by inheriting the class and reimplementing the sort() method though, if you have a look at the documentation for QAbstractItemModel it'll give you some details about it.