I have tried to click a button using id, then class name, then xpath, id is given dynamically. Could you please tell me the exact xpath for this code
package step_definitions;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import cucumber.api.java.en.Given;
import cucumber.api.java.en.Then;
import cucumber.api.java.en.When;
public class sharedshelf {
public WebDriver driver;
public sharedshelf()
{
driver = Hooks.driver;
}
#When("^I press option button$")
public void i_press_option_buttion() throws Throwable {
// Write code here that turns the phrase above into concrete actions
Thread.sleep(5000);
driver.findElement(By.xpath("//button[text()='Edit']")).click();
}
Html
<button type="button" id="ext-gen494" class=" x-btn-text" tabindex="4">Edit</button>
An exception might be thrown when clicking on element in these cases:
If element is disabled and selenium tries to click - it does not automatically wait until it is clickable
Also it can happen if element not visible / element not clickable (hidden under another element)
the solution of waiting until element clickable (under the hood it waits until visible and enabled) will not solve Stale Element Reference Exception
http://docs.seleniumhq.org/exceptions/stale_element_reference.jsp
The best way is to create a method like this:
public void TryClick(By by)
{
DateTime timeout = DateTime.Now.AddSeconds(10);
bool clickedSuccessfully = false;
Exception exceptionWhileClick = null;
do
{
try
{
WrappedElement.FindElement(by).Click();
clickedSuccessfully = true;
}
catch (Exception e)
{
// ignored
exceptionWhileClick = e;
}
} while (!clickedSuccessfully && DateTime.Now < timeout);
if (!clickedSuccessfully && exceptionWhileClick != null)
throw exceptionWhileClick;
}
The button is not clickable when you are trying to click on it. Try waiting for the button to be clickable.
You can also locate the button by partial id using cssSelector By.cssSelector("[id*='ext']")
WebDriverWait wait = new WebDriverWait(driver, 10);
WebElement button = wait.until(ExpectedConditions.elementToBeClickable(By.cssSelector("[id*='ext']")));
button.click();
Related
I'm working with ZK Framework and I need to generate a <listbox> with an 'ListItemRenderer' I'm implementing. The problem is that I need to generate a button inside the renderer pointing to a Composer's method with the onClick event. Here is the code:
ZUL
<window id="mywin" apply="pkg.MyComposer">
<listbox id="mylbx"
model="#{mywin$MyComposer.action}"
itemRenderer="pkg.MyRenderer">
<listhead>
<listheader .../>
...
</listhead>
</listbox>
...
</window>
Composer
package pkg
public class MyComposer extends SelectorComposer<Window> {
#Wire("#mylbx")
private Listbox listbox;
public void action() {
// do some work, added a breakpoint in the first statement
}
Renderer
package pkg
public class MyRenderer implements ListitemRenderer<MyItem> {
#Override
public void render(Listitem item, MyItem data, int index) throws Exception {
// Some rendering...
Listcell actionCell = new Listcell();
this.addButton(actionCell, "Action 1", "btn_action1", index, "50%",
"onClick=mywin$MyComposer.action");
// another button (doesn't matter) ...
actionCell.setParent(item);
}
private void addButton(Listcell parent,
String label,
String id,
int index,
String width,
String forwardAction) {
Button btn = new Button(label);
btn.setId(id + "_" + index);
btn.setClass(id); // Second try
btn.setWidth(width);
ComponentsCtrl.applyForward(btn, forwardAction); // First try
btn.setParent(parent);
}
}
To test if action() is called, I added a breakpoint with my IDE in the first statement of the method, as I say in the comment.
My first try was to add a forward action in addButton(). I took that from another renderer where it was applied to a Span component, but action() was never called.
The second try was to define a class attribute for the button (so every button of the same type gets the same class) and to add an annotation to action() like this:
#Listen("onClick = .btn_action1")
public void actiion() {...}
but the result is the same.
I'm thinking that I need to add an EventListener to the button or to the composer but I don't know how to point to the correct method between the composer and the renderer.
Any help and/or guide is appreciated. Thanks in advance for your answers.
The best way to make this generic is to make a constructor who takes the composer as argument.
Of course, not every composer has that method so you need to create a interface what you will set on the composer.
public interface ButtonListboxRenderer {
void onClickListboxButton(); // of course with return type and arguments you need.
}
Then your renderer :
public class MyRenderer implements ListitemRenderer<MyItem> {
private final ButtonListboxRenderer composer;
public MyRenderer(ButtonListboxRenderer composer) {
this.composer = composer;
}
...
private void addButton(Listcell parent,
String label,
String id,
int index,
String width,
String forwardAction) {
Button btn = new Button(label);
btn.setId(id + "_" + index);
btn.setClass(id); // Second try
btn.setWidth(width);
// add eventlistener to the button and you can point to the method of the composer.
btn.setParent(parent);
}
}
I am trying to show 10,000 contacts on listview in xamarin forms using realm. But whenever user traverse to contact listing screen
it gets freezed and loads after a while.
Moreover , i have provided an option to search from list as well and that too gets stuck as search if performing on UI thread.
Following is the code to load data from realm
public override async Task Initialize(Object data )
{
private Realm _realmInstance = getRealm();
if (contactList != null)
{
contactList.Clear();
}
contactList = _realmInstance.All<Contact>().OrderByDescending(d => d.contactId).ToList();
// here the binding happens with realm data
contacts = new ObservableCollectionFast<Contact>(contactList);
}
public ObservableCollectionFast<Contact> contacts
{
get { return items; }
set
{
items = value;
OnPropertyChanged("contacts");
}
}
as it was taking time in loading i thought to fetch realm data in background and bind it on UI thread as follows
but that is throwing error
realm accessed from incorrect thread
await Task.Run(() => {
contactList = _realmInstance.All<Contact>().OrderByDescending(d => d.contactId).ToList();
});
if (contactList.Count() > 0)
{
ContactListView = true;
AddContactMsg = false;
}
else
{
AddContactMsg = true;
}
Device.BeginInvokeOnMainThread(() =>
{
contacts = new ObservableCollectionFast<Contact>(contactList);
});
i wanted to try limiting the results by using TAKE function of LINQ but unfortunately its not supported by realm yet. not sure how i can smoothly load records from realm to listview.
EDIT
as per the SushiHangover i have changed things from IList to IQueryable
public IQueryable<Contact> contacts
{
get { return items; }
set
{
items = value;
OnPropertyChanged("contacts");
}
}
public override async Task Initialize(Object data )
{
_realmInstance = getRealm();
contacts = dbContactList= _realmInstance.All<Contact>();
}
so far search is working pretty smoothly but IQueryable change leads to another issue. on repeatedly performing following steps results in app crash
tap on list item
detail page gets open then press back
scroll down to few records
perform step 1 and repeat
this results into stackoverflow error
04-19 06:05:13.980 F/art ( 3943): art/runtime/runtime.cc:289]
Pending exception java.lang.StackOverflowError thrown by 'void
md5b60ffeb829f638581ab2bb9b1a7f4f3f.CellAdapter.n_onItemClick(android.widget.AdapterView,
android.view.View, int, long):-2' 04-19 06:05:13.980 F/art (
3943): art/runtime/runtime.cc:289] java.lang.StackOverflowError: stack
size 8MB
Link to entire log file
code to fire item click command is
public ICommand OnContactSelectCommand => new Command<Contact>(OnContactSelect);
following code will open ups a detail page
private async void OnContactSelect(Contact contact)
{
if (contact != null)
{
await NavigationService.NavigateToAsync<ContactDetailViewModel>(contact.mContactId);
}
}
Note:
when i replace IQueryable with List i do not face any error
somehow my issue is related to realm github thread where user is getting exception on listView.SelectedItem = null while using IQueryable
here is my code of list view item tap
private static void ListViewOnItemTapped(object sender, ItemTappedEventArgs e)
{
var listView = sender as ListView;
if (listView != null && listView.IsEnabled && !listView.IsRefreshing)
{
// have commented this line because it was crashing the app
//listView.SelectedItem = null;
var command = GetItemTappedCommand(listView);
if (command != null && command.CanExecute(e.Item))
{
command.Execute(e.Item);
}
}
}
I have an MVC application in which I have to update the view with the current value of a stream.
In the model I have this method:
public Observable<Integer> getStreamInstance(){
if(stream == null){
this.stream = Observable.create((Subscriber<? super Integer> subscriber) -> {
new HeartbeatStream(frequence,subscriber).start();
});
}
return stream;
}
which I use in the controller to get the stream. Then, in the controller I have these two methods:
public void start(){
this.sb = stream.subscribe((Integer v) -> {
view.updateCurrValue(v);
});
}
public void stop(){
this.sb.unsubscribe();
}
With the start method I simply update a label in the view with the current value.
This works fine until I try to stop the updating with the unsubscribing; infact, when I press the button "stop" in the view, the label keeps updating with the current value and, if I press "start" again, the label shows the values from two different streams, the one that I first created with the first "start" and the second that seems has been created with the second pressing of "start".
Where am I wrong?
EDIT:
public class HeartbeatStream extends Thread{
private Subscriber<? super Integer> subscriber;
private int frequence;
private HeartbeatSensor sensor;
public HeartbeatStream(int freq, Subscriber<? super Integer> subscriber){
this.frequence = freq;
this.subscriber = subscriber;
sensor = new HeartbeatSensor();
}
public void run(){
while(true){
try {
subscriber.onNext(sensor.getCurrentValue());
Thread.sleep(frequence);
} catch (Exception e) {
subscriber.onError(e);
}
}
}
This is the HeartbeatStream class. HeartbeatSensor is a class that periodically generates a value that simulates the heartbeat frequence.
I'm guessing you tried to periodically signal some event that triggers the screen update. There is an operator for that:
Observable<Long> timer = Observable.interval(period, TimeUnit.MILLISECONDS,
AndroidSchedulers.mainThread());
SerialSubscription serial = new SerialSubscription();
public void start() {
serial.set(timer.subscribe(v -> view.updateCurrValue(v)));
}
public void stop() {
serial.set(Subscriptions.unsubscribed());
}
public void onDestroy() {
serial.unsubscribe();
}
Observable by design unsubscribe your observer once that all items are emitted and onComplete callback is invoked.
Look this example https://github.com/politrons/reactive/blob/master/src/test/java/rx/observables/creating/ObservableSubscription.java
I guess you're not handling the unsubscribe - although I can't see what's going on in your HeartbeatStream class.
If you're creating an Observable with Observable.create then you need to handle unsubscribing explicitly with subscriber.isUnsubscribed().
Where possible use some of the utility methods to create an Observable - they handle this all for you eg Observable.just() or Observable.from().
If this doesn't help, please post your HeartbeatStream class.
See the the docs for more details:
https://github.com/ReactiveX/RxJava/wiki/Creating-Observables
https://github.com/ReactiveX/RxJava/wiki/Async-Operators
I have a GWT application that features two frames (com.google.gwt.user.client.ui.Frame). Via Frame.setUrl(...) I can load arbitrary web pages without any problems. Of course, user then can click on links on the loaded pages, which in turn load the corresponding pages? How can I keep track of the currently loaded pages in both frames?
Below are my current attempt using two types of listeners; I found the code snippets on the Web. Both events fire, but still I don't know how to get the current loaded URL
import com.google.gwt.event.dom.client.LoadEvent;
import com.google.gwt.event.dom.client.LoadHandler;
import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.Event;
import com.google.gwt.user.client.EventListener;
import com.google.gwt.user.client.ui.Frame;
public class BrowserTabFrame extends Frame implements EventListener {
public BrowserTabFrame() {
super();
sinkEvents(Event.ONLOAD);
addLoadHandler(new LoadHandler() {
#Override
public void onLoad(LoadEvent event) {
System.out.println(event.getSource());
// <iframe style="visibility: visible;" id="ext-gen17" src="http://..." class="gwt-Frame"></iframe>
// however, the src attribute never changes
}
});
}
#Override
public void onBrowserEvent(Event event) {
super.onBrowserEvent(event);
if (DOM.eventGetType(event) == Event.ONLOAD)
System.out.println(event.getCurrentEventTarget());
// [object HTMLIFrameElement]
// no idea what to do with it
}
}
Thanks for any hints!
Christian
The src attribute of an iframe will never change but the URL property of the contained document will. You can get this value using JSNI:
private native String getIframeUrl(IFrameElement frame) /*-{
if (frame.contentDocument !== undefined) {
return frame.contentDocument.URL;
} else if (frame.contentWindow !== undefined &&
frame.contentWindow.document !== undefined)
{
return frame.contentWindow.document;
} else {
return null;
}
}-*/;
...
Window.alert(getIframeUrl(myFrame.getElement()));
However note that, if the security context (any of protocol, domain or port number) of the iframe changes, the browser will not allow the containing application to access the document in the frame.
This is an extension of Jason's solution above. When I tried Jason's code it appeared that the returned URIs are missing hashes (aka fragments, URI suffixes beginning with '#'), and I needed these. After some digging around the DOM spec, the following worked:
public static native String getIframeUri(IFrameElement iframe) /*-{
if (iframe.contentDocument !== undefined) {
if (iframe.contentDocument.defaultView !== undefined
&& iframe.contentDocument.defaultView.location !== undefined) {
return iframe.contentDocument.defaultView.location.href;
} else {
return iframe.contentDocument.URL;
}
} else if (iframe.contentWindow !== undefined
&& iframe.contentWindow.document !== undefined) {
return iframe.contentWindow.document;
} else {
return null;
}
}-*/;
Where the only addition to Jason's code is the nested condition:
if (iframe.contentDocument.defaultView !== undefined
&& iframe.contentDocument.defaultView.location !== undefined) {
return iframe.contentDocument.defaultView.location.href;
I have a simple user control in Windows Phone 7 and I want to get access to the querystring collection from the user controls Constructor. I have tried many ways and cannot seem to get acess to the containing XAML's querystring collection.
Essentially I am navigating to the page and the my user control is going to access the querystring value to write the value back to the interface.
Am I missing adding an assembly or reference or something?
I am not sure you should be trying to get at the information from the page's constructor, as it won't necessairly get called every time you land on this page. A better approach is to override the OnNavigatedTo method inherited from PhoneApplicationPage. Looking a little more carefully at your question, you may be trying to do this within a control embedded in the page, in which case you need to get at the Page in order to obtain the navigation information.
Regardless, the NavigationContext property from the page has a QueryString parameter that you can use to access the information you're after.
The following example assumes I have a parameter named "Message" in the query string when navigating to this page:
public partial class MyPage : PhoneApplicationPage
{
// Constructor
public MyPage()
{
InitializeComponent();
}
protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
{
base.OnNavigatedTo(e);
String navigationMessage;
if (NavigationContext.QueryString.TryGetValue("Message", out navigationMessage))
{
this.textBlock1.Text = navigationMessage;
}
}
}
Sorry about that - I started to get there, and thanks for the clarification. Your best bet then is to walk up the visual tree from your control to find the Page, then you can have at the NavigationContext. In my sample below, I have a button on a custom control within the page, whose click event finds the nav context and looks for a certain navigation parameter - I couldn't tell from the question or your follow-up what would drive the control to "want" to find the content of the query string.
(Note about getting info from the ctor follows the code below)
public partial class WindowsPhoneControl1 : UserControl
{
public WindowsPhoneControl1()
{
InitializeComponent();
}
private void button1_Click(object sender, RoutedEventArgs e)
{
GetTheQueryString();
}
private void GetTheQueryString()
{
var result = "No Joy";
var page = FindRootPage(this);
if (page != null)
{
if (page.NavigationContext.QueryString.ContainsKey("Param"))
{
result = page.NavigationContext.QueryString["Param"];
}
}
queryStringText.Text = result;
}
private static PhoneApplicationPage FindRootPage(FrameworkElement item)
{
if (item != null && !(item is PhoneApplicationPage))
{
item = FindRootPage(item.Parent as FrameworkElement);
}
return item as PhoneApplicationPage;
}
}
Note that this won't work from the ctor because of how Xaml works...the Xml tag drives the ctor to be called, then properties are set as indicated, then it is added as a child/item/etc in its container. If you do need to get at the context ASAP using this "walk up the tree" technique, handle the Control's Loaded event, by which time the control does have a parent and a tree that can be walked...
public WindowsPhoneControl1()
{
InitializeComponent();
Loaded += WindowsPhoneControl1_Loaded;
}
private void WindowsPhoneControl1_Loaded(Object sender, RoutedEventArgs e)
{
GetTheQueryString();
}
I would add a property to the UserControl subclass that would be set by the page in its OnNavigatedTo() method.