0

With Selenium, I'm filling in a form, clicking on a button that takes me to a new page on the same tab, then I want to be able to click on a button in the new page. however I'm getting

no such element: Unable to locate element: {"method":"css selector","selector":"*[id="widget_5052246"]"}

I figured out that it's not waiting for my page to load fully, before trying to click on the next button. So I looked around and found this. added

driver.wait(function() {
  return driver.executeScript('return document.readyState').then(function(readyState) {
    return readyState === 'complete';
  });
}); 

However, it didn't work...

Found that I could do

await driver.wait(until.elementLocated(By.id("widget_5052246")), 20000)

then after click on the element.

But I'm getting

Error: Timeout of 30000ms exceeded. For async tests and hooks, ensure "done()" is called; if returning a Promise, ensure it resolves.

So yeah I'm not sure how I can wait for the page to load correctly...

HTML code of button :

<button id="widget_5052246" class="adbx-widget btn btn-default" data-action="play" ng-style="vm.style" ng-click="vm.click($event);" ng-mouseover="vm.onMouseOver()" ng-mouseleave="vm.onMouseLeave()" ng-mousedown="vm.onMouseDown()" ng-mouseup="vm.onMouseUp()" ng-touchstart="vm.onTouchStart()" ng-touchend="vm.onTouchEnd()" ng-hide="vm.hide" identifier="5052246" aria-hidden="false" style="visibility: visible; width: auto; height: auto; left: 260px; top: 253px; z-index: 1; transform: rotate(0deg); cursor: pointer; outline: none;"><!-- ngIf: vm.styleClass === '' --> <!-- ngIf: vm.styleClass !== '' --><span ng-if="vm.styleClass !== ''" disabled="disabled" style="opacity: 1; cursor: pointer" translate="Cliquez pour découvrir si vous avez gagné" class="ng-scope ng-binding">Cliquez pour découvrir si vous avez gagné</span><!-- end ngIf: vm.styleClass !== '' --></button>

Found that the problem wasn't that the load time wasn't happening but that the click wasn't going through. That click usually lead to a new page yet it never would go to that next page.

Edit : Added code of button

Joel
  • 5
  • 4
  • This id `widget_5052246` does not seems to be static, can you share the HTML code for this button ? – cruisepandey Sep 27 '21 at 08:59
  • you shouldn't wait for `readyState === 'complete'`. It's on by default. – Alexey R. Sep 27 '21 at 09:03
  • @cruisepandey I added the code for the button. – Joel Sep 27 '21 at 09:08
  • @Joel : I do not understand the unacceptance, this ticket was solely for locator and clicking issue, which we resolved it, see your comments below, after that somewhere you could not perform the click, if your requirement has changes, please try to submit a new ticket instead. – cruisepandey Oct 01 '21 at 12:39

1 Answers1

0

Based on the HTML shared by OP, I have constructed this xpath

//button[starts-with(@id,'widget') and starts-with(@class,'adbx-widget') and @identifier]

first you should check whether we have unique matching node in HTMLDOM or not.

PS : Please check in the dev tools (Google chrome) if we have unique entry in HTML DOM or not.

Steps to check:

Press F12 in Chrome -> go to element section -> do a CTRL + F -> then paste the xpath and see, if your desired element is getting highlighted with 1/1 matching node.

If we have unique entry we can proceed further to how to click on this element.

let ele = await driver.wait(until.elementLocated(By.xpath("//button[starts-with(@id,'widget') and starts-with(@class,'adbx-widget') and @identifier]")),10000);
ele.click();

Please refer here for more on explicit waits.

Update :

In python, I would have this script :

driver = webdriver.Chrome(driver_path)
driver.maximize_window()
driver.implicitly_wait(30)
wait = WebDriverWait(driver, 30)
driver.get("https://adbx.io/click-win-gujx1tfvdf/0/o4R2a/")

wait.until(EC.element_to_be_clickable((By.ID, "cookies-banner-confirmation-button"))).click()  #to click on Accepter button.
wait.until(EC.element_to_be_clickable((By.ID, "lastname"))).send_keys('fakelastname') # to send Nom*
wait.until(EC.element_to_be_clickable((By.ID, "firstname"))).send_keys('fakeFirstName') # to send Prenom*
wait.until(EC.element_to_be_clickable((By.ID, "email"))).send_keys('fakeEmail@hotmail.com') # to send Email*
wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, "div.md-container.md-ink-ripple"))).click()  # to click the J'accepte le règlement*

wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, "button[ng-click='vm.click($event);']"))).click()  # to click on Valider

wait.until(EC.element_to_be_clickable((By.XPATH, "//button[@data-action]"))).click()  # to click on Cliquez pour découvrir si vous avez gagné

ele = wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, "div[ng-bind-html='vm.text']")))
print(ele.text)
cruisepandey
  • 28,520
  • 6
  • 20
  • 38
  • `(//button[starts-with(@id,'widget') and starts-with(@class,'adbx-widget') and @identifier])[1]` may be xpath indexing like this, you can change the `[1]` to `[2]` or so on.. but make sure that you've unique matching node in HTMLDOM, that is 1/1 – cruisepandey Sep 27 '21 at 14:11
  • For this particular problem it's working well... After the click was made, I have to do another click, I used a similar code only thing is my modified the xpath so it can find place to click on. I'm getting timeout error again – Joel Sep 27 '21 at 14:23
  • @Joel : I need to see the HTML to guide you further. – cruisepandey Sep 27 '21 at 14:28
  • here's the [website](https://adbx.io/click-win-gujx1tfvdf/0/o4R2a/) . put fake name,surname, email. I can click the first submit button, the second button you'll see is the one we targetted in the problem and next there's a "result" page where I'm clicking on "Bravo..." (later will assert). Need to remove cookies at every reload and use different email address – Joel Sep 27 '21 at 14:41
  • I did follow all the steps that you've mentioned above, and after clicking on `//button[starts-with(@id,'widget') and starts-with(@class,'adbx-widget') and @identifier]` I got this as a outerHTML – cruisepandey Sep 27 '21 at 17:58
  • ng-hide="vm.hide" identifier="5052246" aria-hidden="false" style="visibility: visible; width: auto; height: auto; left: 260px; top: 253px; z-index: 1; transform: rotate(0deg); cursor: pointer; outline: none;"> Cliquez pour découvrir si vous avez gagné – cruisepandey Sep 27 '21 at 17:59
  • Which does not have any `Bravo` in it. – cruisepandey Sep 27 '21 at 17:59
  • After clicking on the button where it says "Cliquez pour découvrir si vous avez gagné", you'll see a page with a text that says "Bravo..." – Joel Sep 28 '21 at 07:10
  • I think the error I'm getting is because the `let ele = await driver.wait(until.elementLocated(By.xpath("//button[starts-with(@id,'widget') and starts-with(@class,'adbx-widget') and @identifier]")),10000); ele.click();`Is finding my button but the click isn't passing through. I'm not getting sent to the next page – Joel Sep 28 '21 at 07:50
  • After clicking on this button `Cliquez pour découvrir si vous avez gagné`, all I see is `Invitez vos amis à participer et tenter de gagner :` with 2 buttons `Partager avec Facebook` and `Partager avec Twitter`. Is it a German or French language ? I can probably use google translate. – cruisepandey Sep 28 '21 at 08:56
  • That's because everytime, you need to make sure the cookies are deleted. Also the email always needs to be different. [Here's my code so you can test it out for yourself](https://gist.github.com/jolio007/26cfc9fac4036967c074667f54570ab1) – Joel Sep 28 '21 at 12:11
  • okay I do see this line `Bravo, vous remportez Menu McDo :` but I can not perform click manually, so Selenium won't be able to click either. I do not have a environment setup to run JS code, I generally work with Python, C#, and Java. – cruisepandey Sep 28 '21 at 12:58
  • Meanwhile you can try with xpath as well `//div[contains(text(),'Bravo')]` this is based on text. – cruisepandey Sep 28 '21 at 13:03
  • The thing is I'm never getting to that line. What happens is that I'm unsure if the click on the button really worked as when it's looking for the text, it's returning an error. Also visually, I never see it when I'm running the code. So I'm wondering if the problem isn't with the `et ele = await driver.wait(until.elementLocated(By.xpath("//button[starts-with(@id,'widget') and starts-with(@class,'adbx-widget') and @identifier]")),10000); ele.click();`line – Joel Sep 28 '21 at 14:06
  • I will try the same in python tomorrow morning IST, will let you know. – cruisepandey Sep 28 '21 at 17:41
  • @Joel : Please see above, code is in python you can possibly convert to JS with the locators. – cruisepandey Sep 29 '21 at 07:45
  • I modified my code like yours but for some odd reason, the click on `Cliquez pour découvrir si vous avez gagné` is telling me that it's has been done but I'm staying on the same page. I commented out the code below the click and it's saying my test is successful however the click isn't taking me to the next page. I change click for a double click and also added another click on the button and I'm still getting the same problem – Joel Sep 29 '21 at 15:43
  • Can you update your question with the recent code ? – cruisepandey Sep 29 '21 at 15:51