I'm making a sneaker bot that simulates a checkout on shoe palace (using air force 1s as an example in this program). Basically what I'm having trouble with is after about 5 seconds after opening the website (it's not a consistent amount of time) I get a popup basically just advertising signing up for their club or whatever and it screws up my code because the button doesn't get pressed so the script terminates. I've tried using time.sleep(5) to hopefully wait for it to popup and then simulating pressing the escape key to close it but it just doesn't work. Is there a way that I can recognize when the popup comes up so I can run a piece of code that closes it immediately? Below I have the code I'm using currently which in an instance where the popup doesn't come up works perfectly. Any help is GREATLY appreciated as I've been stumped with this problem.
from selenium import webdriver
import time
# from pynput.keyboard import Key, Controller
# keyboard = Controller()
PATH = "C:\Program Files (x86)\chromedriver.exe"
driver = webdriver.Chrome(PATH)
#driver.delete_all_cookies()
#open product page (CHANGE THIS)
#driver.get('https://www.shoepalace.com/product/nike/ck7214-100/air-force-1-07-lv8-2-mens-lifestyle-shoe-white-white/')
driver.get('https://www.shoepalace.com/product/nike/ck7214-100/air-force-1-07-lv8-2-mens-lifestyle-shoe-white-white/')
time.sleep(.025)
#secondary size
button = driver.find_element_by_xpath("/html/body/div[2]/div[4]/form/div[1]/button[5]")
button.click()
#primary size
button = driver.find_element_by_xpath("/html/body/div[2]/div[4]/form/div[1]/button[7]")
button.click()
#add to cart
button = driver.find_element_by_xpath("/html/body/div[2]/div[4]/form/div[2]/input")
button.click()
#checkout
button = driver.find_element_by_xpath("/html/body/div[2]/div/div[2]/div/div/div/ul[2]/li[1]")
button.click()
You can create a method where you should:
Identify if the pop-up is displayed
Close it if so
Wait until pop-up is not displayed
Keep in mind that your code runs line by line, so if you know when the pop up can appear, you can add your method there. If not, based on your code structure is a tricky one because you will need to add it before each action.
Related
Trying to automate amazon affiliate report generation. cannot change the value of a checkbox
need to mark this checkbox
this is HTML of that checkbok
radio = driver.find_element_by_xpath(
"//input[#value='custom' and #name='ac-daterange-radio-report-download-timeInterval']")
driver.execute_script("arguments[0].click();", radio)
# driver.execute_script(
# "arguments[0].setAttribute('checked', 'checked';", radio)
If more clarity needed can ask here.
thanks in advance
You are not sending click event to java script executor, instead of this you directly click by .click() method. If you want to click one of the checkbox you use one of the following commands, change the text contains: Today, Yesterday and other. See this:
driver.find_element_by_xpath("//span[contains(text(), 'Today')]/ancestor::label/input").click()
driver.find_element_by_xpath("//span[contains(text(), 'Yesterday')]/ancestor::label/input").click()
driver.find_element_by_xpath("//span[contains(text(), 'Custom Date Range')]/ancestor::label/input").click()
I have an application flow which looks like this. At startup a MainWindow is shown and asks the user to choose a project or create a new one. After a project is created or chosen from the list, I want to close this MainWindow and open another MainWindow.
In my main.py the code looks like this:
app = QApplication([])
ui_project_list_view = ProjectListView()
ui_project_list_view.show()
app.exec_()
Now I want to close the first main window (ui_project_list_view) and open the other main window (ui_project_view). This code is called from within ui_project_list_view.
ui_project_view = ProjectView()
ui_project_view.show()
main_view.close()
No matter in which order I show or close, the application quits. How should I design my "window-flow" ?
Thanks for your help.
If you open most programs like Word or Excel- or QtDesigner for example- you'll see a blank main window initialize, and then a popup will appear asking you to choose your project.
If you wanted to apply this to your code, the ProjectView should be the main window and the ProjectListView would be the popup. The ProjectView would call this after initializing, in a setup function perhaps. After ProjectListView finishes, then ProjectView would just need to update the screen with the information that ProjectListView has.
I am working with Selenium python, and would like to scroll down on a page after clicking an element. Clicking the element gives a pop-up menu, and then when I try some scrolling methods they scroll on the original page.
I have selected the body of the new element that has appeared and tried this:
from selenium import webdriver
from selenium import Keys
driver = webdriver.get(url)
button = driver.find_element_by_xpath(pathto)
button.click()
body = driver.find_element_by_css('body')
body.send_keys(Keys.PAGE_DOWN)
This does not actually do anything as is. However, if I first manually click on the new popup element before doing body.send_keys(Keys.PAGE_DOWN), it does scroll.
One way I have resolved this is using ActionChains to right click on the body before scrolling down. Directly using .click() on the body does not work as it clicks a link in the body.
Are there any better ways to do this? In particular, I am somewhat afraid that the right click menu that opens up when I use my current method may mess with the rest of the scraping. Is there at least a method to guarantee that it does not interfere? Another solution could be somehow "selecting" or clicking on the body element within selenium, so are there any suggestions for this?
You could try using END key instead of DOWN key. It's worth a shot:
from selenium.webdriver.common.keys import Keys
driver = webdriver.get(url)
button = driver.find_element_by_xpath(pathto)
button.click()
driver.find_element_by_tag_name('body').send_keys(Keys.END)
You also may need to click the pop-up in order to focus it first:
from selenium.webdriver.common.keys import Keys
driver = webdriver.get(url)
button = driver.find_element_by_xpath(pathto)
button.click()
# click popup menu to get it into focus
popup_menu = driver.find_element_by_xpath(pathToPopupMenu)
popup_menu.click()
driver.find_element_by_tag_name('body').send_keys(Keys.END)
We have a Form that is shown as a Dialogue above the main Form.
DialogResult rslt = cvForm.ShowDialog();
In Coded UI test, immediately when the Dialogue is lunched, the Mouse.Click tries to close it by clicking the "x" button of the Form.
However, seems the x button cannot respond the click event sometimes, on a certain machine it always fails to close the Form unless we put a wait before the click.
All WaitForControlxxx() does not serve as wait because they immediately returns.
Only putting PlayWait(1000) before the click works and can close the Form.
And the failure only happens on our lab machine. On my laptop, even without PlayWait(1000), it works fine.
Seems it's only a timing issue.
Is there anything I can wait for instead of blindly wait for 1 second in order for it to work on the lab machine?
//this.UIAUDIO_TX_HPF_IIRWindow refers to the Form shown as a Dialogue:
// this.UIAUDIO_TX_HPF_IIRWindow
//ulCloseButton refers to the "x" button on the Form:
WinButton uICloseButton = this.UIAUDIO_TX_HPF_IIRWindow.UIAUDIO_TX_HPF_IIRTitleBar.UICloseButton;
The following code cannot close the WinForm window on our lab machine, but CAN close it on my laptop machine:
uICloseButton.WaitForControlExist();
uICloseButton.WaitForControlReady();
uICloseButton.WaitForControlEnabled();
this.UIAUDIO_TX_HPF_IIRWindow.WaitForControlReady();
//Mouse.Click(uICloseButton, new Point(15, 9));
Mouse.Click(uICloseButton);
The following code CAN close the WinForm window on our lab machine:
Playback.Wait(1000);
Mouse.Click(uICloseButton);
Any comments?
It seems dialog is not completely ready to change focus on dialog.
Before focus gets ready, test is trying to close it.
Try with following code.
Playback.PlaybackSettings.WaitForReadyLevel = WaitForReadyLevel.AllThreads;
Here WaitForReadyLevel.UIThreads option also present.
This will increase test execution time.
Let me quickly explain the background to this. I'm developing a custom menu system inside a 3D application called Softimage XSI. It has a PyQt application object created already and ProcessEvents is being called a certain number of times every second so that PyQt applications can exist in a non-modal state within XSI.
To implement the menu, I've got a webpage embedded in a toolbar which is calling a plugin for XSI that I've written to show a PyQt menu. This all works fine (albeit, slightly contrived!).
The issue is that when I show the menu, it won't disappear when I click away from it. If I move the mouse over the menu, and then click away from it, it will disappear. It's only when it first pops up.
I've tried everything I can think of. Here's a list:
Using QtGui.qApp.installEventFilter(menu) to try and catch the mousepressed signal. It never gets triggered. I suspect the application itself isn't receiving the click.
Using menu.raise_() makes no difference
Neither does QtGui.qApp.setActiveWindow(menu)
Or menu.setFocus()
I've also tried:
event = QtGui.QMouseEvent(QtCore.QEvent.MouseMove, pos, QtCore.Qt.NoButton, QtCore.Qt.NoButton, QtCore.Qt.NoModifier)
QtGui.qApp.sendEvent(menu, event)
I had a go writing my own QEventLoop, but it just crashed XSI. I suspect trying to run a modal loop inside the other one probably isn't a legal thing to do. Either that, or I really don't know what I'm doing (equally probable)
The only thing I have partial success with is using grabMouse(). This is what makes the menu close if I click away from the menu (only after the mouse has passed over the menu once), but I have to call it a couple of times for it to "stick".
So this is my code at the moment:
class MyMenu (QtGui.QMenu):
def __init__(self, parent = None):
QtGui.QMenu.__init__(self, parent)
self.grabbed=2
def getMouse(self):
if self.grabbed>0:
self.grabMouse()
self.grabbed-=1
def paintEvent(self, event):
QtGui.QMenu.paintEvent(self, event)
self.getMouse()
def hideEvent(self, event):
self.releaseMouse()
def ShowMenu():
menu = MyMenu()
menu.addAction("A")
menu.addAction("B")
menu.addAction("C")
submenu = MyMenu()
submenu.addAction("D")
submenu.addAction("E")
submenu.addAction("F")
menu.addMenu(submenu)
menu.setTearOffEnabled(True)
menu.setStyleSheet("font: 8pt \"Sans Serif\";")
submenu.setStyleSheet("font: 8pt \"Sans Serif\";")
submenu.setTitle("Window")
submenu.setTearOffEnabled(True)
pos = QtGui.QCursor.pos()
pos.setX(105)
menu.popup(pos)
#Prevent garbage collection
QtGui.XSIMenu=menu
QtGui.XSISubMenu=submenu
#Desperate acts!
menu.raise_()
QtGui.qApp.setActiveWindow(menu)
menu.setFocus()
Any thoughts or random suggestions would be very gratefully received as this is driving me nuts! Don't be afraid to suggest modifications to stuff I've already tried, as I'm relatively new to PyQt and I may well have missed something.
Many thanks,
Andy
Just before calling popup with self.trayMenu.popup(QtGui.QCursor.pos()), call self.trayMenu.activateWindow(). Putting activateWindow before popup makes the left-click menu work the same as the right-click menu and it goes away when you click elsewhere. :)