如何使用 selenium 测试 jquery ajax 选项卡?

发布于 2024-09-06 15:08:36 字数 1806 浏览 7 评论 0原文

我正在使用 selenium 测试 django 应用程序,我的一个页面使用 jquery ui tabs 元素。其中一个选项卡包含一个简单的表格,列出了一些用户,并通过 ajax 加载。使用该应用程序时,该选项卡工作得很好,但是当使用 selenium 自动化测试时,该选项卡似乎没有加载其内容! 我自己用 python 编写测试。起初,我使用的是 selenium RC 的 click 方法,但正如我从之前的测试中痛苦地了解到的那样,当涉及到锚标记时,这是相当有问题的,所以我采用了我的解决方案之前使用过: wait_for_condition 方法并显式调用选项卡单击事件(甚至加载事件!),但选项卡仍然无法工作!

我在这里感到绝望,我的大部分测试都依赖于该页面,并且几乎一半都在该表上,但是,唉,似乎硒正在搞砸 JavaScript! (我在课堂上还有其他测试,它们运行得很好,所以在服务器级别没有发生任何奇怪的事情,这似乎是客户端硒引起的问题) 我的测试代码与此类似:

class TestMyApp(TransactionTestCase):
urls = 'myapp.test_urls'

def setUp(self):
    self.verificationErrors = []
    self.selenium = selenium("localhost", 4444, "*chrome", "http://localhost:8000/")
    self.selenium.start()
    #self.selenium.set_speed(2000)
    self.selenium.window_maximize()
def test_users_list(self):
    """Test that an app's users are correctly listed"""
    sel = self.selenium
    users = []
    for u in range(settings.FREE_USER_LIMIT/2):
        users.append(self.app.users.create(name="testUser_%s"%uuid4()))

    sel.open("/")        
    sel.wait_for_page_to_load("30000")
    sel.wait_for_condition('selenium.browserbot.getCurrentWindow().jQuery("#tabs").tabs("select",1);\
    selenium.browserbot.getCurrentWindow().jQuery("#tabs").tabs("load",1);',
                             3000)
    for user in users:
        try: self.failUnless(sel.is_text_present(user.name))
        except AssertionError, e: self.verificationErrors.append(str(e))
        try: self.failUnless(sel.is_text_present(str(user.added.date())))
        except AssertionError, e: self.verificationErrors.append(str(e))
def tearDown(self):
    self.selenium.stop()
    self.assertEqual([], self.verificationErrors)

I'm testing a django app with selenium, and one of my pages uses the jquery ui tabs element. One of the tabs contains a simple table listing some users, and is loaded via ajax. When using the app, the tab works just fine, but when automating the test with selenium, the tab doesn't appear to load it's content!
I'm writing the tests myself in python. At first, I was using the click method of selenium RC, but as I -painfully- learned from a previous test, that is rather buggy when it comes to anchor tags, so I resorted to the solution I used before: the wait_for_condition method and explicitly called the tab click event (and even the load event!) and nevertheless the tab was still not working!

I'm in despair here, the majority of my tests depend on that page and almost half of them are on that table, but, alas, it seems selenium is screwing up the javascript!
(I have other tests in the class, and they run just fine, so nothing weird is going on at the server level, it seems to be a problem caused by selenium in the client side)
My test code is similar to this:

class TestMyApp(TransactionTestCase):
urls = 'myapp.test_urls'

def setUp(self):
    self.verificationErrors = []
    self.selenium = selenium("localhost", 4444, "*chrome", "http://localhost:8000/")
    self.selenium.start()
    #self.selenium.set_speed(2000)
    self.selenium.window_maximize()
def test_users_list(self):
    """Test that an app's users are correctly listed"""
    sel = self.selenium
    users = []
    for u in range(settings.FREE_USER_LIMIT/2):
        users.append(self.app.users.create(name="testUser_%s"%uuid4()))

    sel.open("/")        
    sel.wait_for_page_to_load("30000")
    sel.wait_for_condition('selenium.browserbot.getCurrentWindow().jQuery("#tabs").tabs("select",1);\
    selenium.browserbot.getCurrentWindow().jQuery("#tabs").tabs("load",1);',
                             3000)
    for user in users:
        try: self.failUnless(sel.is_text_present(user.name))
        except AssertionError, e: self.verificationErrors.append(str(e))
        try: self.failUnless(sel.is_text_present(str(user.added.date())))
        except AssertionError, e: self.verificationErrors.append(str(e))
def tearDown(self):
    self.selenium.stop()
    self.assertEqual([], self.verificationErrors)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

单挑你×的.吻 2024-09-13 15:08:37

这可能有几件事。可能是 Selenium 在点击锚点时遇到了问题,但实际上我还没有听说过这个问题,而且听起来不太可能。听起来 click() 方法返回 OK,它不会给你“找不到元素”,对吗?当您单击 jquery 选项卡时,javascript 并没有执行预期的操作。根据我的经验,这通常会归结为同样的问题——因为当 javascript 渲染页面的一部分并连续影响 DOM 时,Selenium 执行得非常快,有时当 Selenium 与页面的动态生成部分交互时(比如单击此按钮)选项卡),它与之交互的部分取决于实际上尚未完全加载的其他部分。事实上,距离完全加载可能只有几微秒的时间,但硒太快了。当然,您已经理解了这一点,您对 wait_for 条件寻找要加载的选项卡有正确的想法。我的猜测是可能还不够长。您必须找到一些评估来表明整个 UI 选项卡已加载并呈现。选项卡 API 是否有一些可以添加的回调来设置“完成加载”变量,或者它是否公开了类似的变量?除非找出正确的表达方式来找到 UI 选项卡实际准备好单击的时间点(这可能会很棘手),否则您可以采取彻底暂停的方式来确保页面的该部分在此之前已准备好运行你与它互动。我认为代码中的 sleep(2) 甚至 sleep(5) 等都没有问题(如果有必要让它工作)。测试这是否真的发生的一种方法是在交互式解释器中启动场景(我喜欢 Python,用 Java 做这件事真是太棒了)。逐行粘贴代码以到达问题点,或者注释掉拆卸方法中的 selenium.stop() 调用以及问题点之后的任何测试代码,这样它就会使 selenium 窗口保持打开状态并退出。然后在交互式解释器中实例化一个selenium对象并劫持打开的会话:

selenium = selenium("localhost", 4444, "*chrome", "http://localhost:8000/")
selenium.sessionId = "0asdd234234023424foo" #Get this from the Se window

...以获取窗口的交互式控制。然后,您可以了解如何进行 selenium.click() 或进行 selenium.get_eval('...js...') 调用来调查当时的 javascript 情况时间点。我的猜测是,当您这样做时,当您输入时,click()实际上会正常工作,因为当您加载会话并开始输入selenium.click时('blah_tab_locator'),选项卡内容将全部加载并准备就绪。只是当 Python 进行调用时,当进行这些动态渲染时,它对浏览器来说速度太快了。如果当您像这样通过 Selenium 手动执行操作时点击工作正常,那么您就知道这是一个计时问题。找到合适的 wait_for_condition 或屈尊使用 python sleep()。否则,如果执行此操作时点击仍然不起作用,则可能是所使用的定位器出现问题。选项卡 UI 在选项卡结构的某些部分上具有单击、鼠标松开、焦点或某种事件处理程序,也许只是找到要单击的选项卡的正确部分或要触发的正确事件。如果不是这样,那么可能就像您提到的 Selenium 和 Jquery UI 之间的某种奇怪的交互一样,但这会让我感到惊讶,我很想知道。如果是这样,请使用 get_eval() 查看 javascript 中发生的情况。不过,对我来说,这听起来像是一个时间问题。

This could be a few things. It could be that Selenium is having trouble clicking the anchor but I actually haven't heard of that trouble and it sounds less likely. It sounds like the click() method returns OK, it doesn't give you "element not found", right? When you do the click the jquery tab javascript just isn't doing what's expected. In my experience this usually comes down to the same issue -- since Selenium executes very quickly, when javascript is rendering portions of the page and effecting the DOM continuously sometimes when Selenium goes to interact with dynamically generated parts of the page (say to click this tab), the piece it's interacting with depends on some other piece that actually hasn't fully loaded yet. It's probably microseconds away from fully loading in fact, but selenium is too fast. You already understand this of course, you have the right idea with the wait_for condition looking for the tabs to be loaded. My guess would be it's probably just not long enough. You have to find some evaluation to make that says the whole UI tabs thing is loaded and rendered. Does the tabs API have some callbacks you can add to set a "done loading" variable or does it expose a variable like that? Barring figuring out what the proper expression is to find the point in time when the UI tabs are actually ready to be clicked, which possibly could be tricky, you can resort to outright pauses to make sure the part of the page is ready to go before you interact with it. I see no problem in sleep(2), or even sleep(5), etc. in the code if it's necessary to get it to work. One way you can test that this is really what's going on is by firing up the scenario in the interactive interpreter (gotta love Python, beats the pants off of doing this in Java). Paste the code in line by line to get to the trouble point, or comment out the selenium.stop() call in your teardown method and any test code after the trouble point, so it leaves the selenium window open and exits. Then instantiate a selenium object in the interactive interpretter and hijack the open session:

selenium = selenium("localhost", 4444, "*chrome", "http://localhost:8000/")
selenium.sessionId = "0asdd234234023424foo" #Get this from the Se window

...to get interactive control of the window. Then you can see about making the selenium.click() or make selenium.get_eval('...js...') calls to investigate the javascript landscape at that point in time. My guess is when you do this, the click() will actually work fine when you type it in, because by the time you get the session loaded and get around to typing in selenium.click('blah_tab_locator'), the tab guts will all be loaded and ready to go. It's just that when Python is making the calls it does it way too fast for the browser when there are these dynamic renderings going on. If the click works fine when you do it manually through selenium like this, then you know it's a timing issue. Find that proper wait_for_condition or condescend to a python sleep(). Otherwise, if the click continues to not work when you do this, then it's probably a problem with the locator being used. The tab UI has a click or a mouseup or a focus or some kind of event handler on some part of the tab structure, maybe it's just about finding the right part of the tab to click or the right event to fire. If it isn't that then it perhaps could be as you mention some kind of strange interaction between Selenium and Jquery UI, but that would surprise me and I'd be curious to know. Poke around with get_eval() to see what's going on in the javascript if so. It sounds like a timing issue to me though.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文