सेलेनियम में जावास्क्रिप्ट त्रुटि कैप्चर करना


81

वहाँ में होने वाली त्रुटियों पर कब्जा करने के लिए एक रास्ता है DOMमें Seleniumऔर शायद पेज में किसी त्रुटि के रूप में ही फ़्लैग करें?

एक संक्षिप्त उदाहरण देने के लिए, मान लें कि मैं एक गैर-मौजूदा HTML नियंत्रण पर एक घटना को बांधने की कोशिश कर रहा हूं, मेरा ब्राउज़र एक त्रुटि कह रहा है:

element abcd not found in the console.

अब, यदि मैं अपने सेलेनियम परीक्षणों को विफल करने के लिए एक ही त्रुटि चाहता हूं और ब्राउज़र पर दिखाया गया संदेश त्रुटि संदेश के रूप में दिखाया गया है।

क्या ऐसा कुछ करना संभव है?


1
यह अब 2018 है, क्या कोई क्लीनर समाधान है?
Fla

जवाबों:


52

इस स्क्रिप्ट को अपने पेज पर रखें और फिर सेसेरियम में JSError के लिए जाँच करें:

<script type="text/javascript">
    window.onerror=function(msg){
        $("body").attr("JSError",msg);
    }
</script>

3
इसे आसानी से उस मामले को पकड़ने के लिए भी बढ़ाया जा सकता है जहां JQuery ने लोड नहीं किया: ऑनरोर कॉल के बाहर एक $ ('बॉडी') जोड़ें। attr ("JQLoaded", "Yes")। तब JSError की सेलेनियम उपस्थिति में, या JQLoaded की अनुपस्थिति, एक जावास्क्रिप्ट त्रुटि का संकेत देती है।
निल्स

51
या आप सिर्फ document.body.setAttribute("JSError", msg)jQuery के आधार पर कह सकते हैं
कोस

3
क्या इसे HTML पेज में हमेशा के लिए जोड़ा जा सकता है, या डायनामिकली जब परीक्षण चलाया जाता है ?? मुझे यकीन नहीं है कि मैं डेवलपर्स को हर पेज पर उस स्निपेट को जोड़ने के लिए मनाऊंगा। मेरे लिए विवरण साझा करने के लिए धन्यवाद।
मिशाल

3
लिंक किया गया पृष्ठ अब उपलब्ध नहीं है।
क्रिस बी

54

मैं जावास्क्रिप्ट त्रुटियों को पकड़ने के लिए यह कर रहा हूँ:

[TestCleanup]
public void TestCleanup()
{
    var errorStrings = new List<string> 
    { 
        "SyntaxError", 
        "EvalError", 
        "ReferenceError", 
        "RangeError", 
        "TypeError", 
        "URIError" 
    };

    var jsErrors = Driver.Manage().Logs.GetLog(LogType.Browser).Where(x => errorStrings.Any(e => x.Message.Contains(e)));

    if (jsErrors.Any())
    {
        Assert.Fail("JavaScript error(s):" + Environment.NewLine + jsErrors.Aggregate("", (s, entry) => s + entry.Message + Environment.NewLine));
    }
}

3
वास्तव में इस समाधान की तरह
Rob G

2
सेलेनियम ड्राइवर 3.6.0 और फ़ायरफ़ॉक्स 56.0 के नवीनतम संस्करण का उपयोग करते हुए, "गेटलॉग" विधि एक "ऑब्जेक्ट संदर्भ को किसी ऑब्जेक्ट की आवृत्ति पर सेट नहीं है" फेंकता है, निश्चित रूप से क्यों नहीं ... यह वेबड्राइवर / पुराने संस्करण में काम करता है। फ़ायरफ़ॉक्स
डेविड रोजर्स

2
@DavidRogers मुझे लगता है कि यह अब इस वजह से जियोक्रोडाइवर पर काम नहीं कर रहा है: github.com/mozilla/geckodriver/issues/284
ईसाई हुजेर

19

यकीन नहीं है कि यह कब बदल गया, लेकिन अभी यह मेरे लिए पायथन में काम करता है। फ़ाइल एक जावास्क्रिप्ट त्रुटि के साथ एक सरल पृष्ठ है।

In [11]: driver.get("file:///tmp/a.html")

In [12]: driver.get_log("browser")
Out[12]: 
[{u'level': u'SEVERE',
  u'message': u'ReferenceError: foo is not defined',
  u'timestamp': 1450769357488,
  u'type': u''},
 {u'level': u'INFO',
  u'message': u'The character encoding of the HTML document was not declared. The document will render with garbled text in some browser configurations if the document contains characters from outside the US-ASCII range. The character encoding of the page must be declared in the document or in the transfer protocol.',
  u'timestamp': 1450769357498,
  u'type': u''}]

पायथन-सेलेनियम संस्करण 2.48.0 लिनक्स फ़ायरफ़ॉक्स 43.0


यह webdriver.io के साथ भी काम करता है। driver.log("browser").then(function(results){ console.log(results.value); }
टायलर हॉकिन्स

यह वर्तमान में फ़ायरफ़ॉक्स के साथ इस मुद्दे के कारण काम नहीं करेगा: github.com/mozilla/geckodriver/issues/284
क्रिश्चियन हुजेर

7

यहाँ अजगर वेबड्राइवर समाधान का उपयोग करता हूं:

def check_browser_errors(driver):
    """
    Checks browser for errors, returns a list of errors
    :param driver:
    :return:
    """
    try:
        browserlogs = driver.get_log('browser')
    except (ValueError, WebDriverException) as e:
        # Some browsers does not support getting logs
        LOGGER.debug("Could not get browser logs for driver %s due to exception: %s",
                     driver, e)
        return []

    errors = []
    for entry in browserlogs:
        if entry['level'] == 'SEVERE':
            errors.append(entry)
    return errors

6

JSErrorCollector काम करता है।

एक बार कॉन्फ़िगर करने के बाद, यह निम्न का विषय है:

List<JavaScriptError> jsErrorList = JavaScriptError.readErrors(driver);

2
FYI करें: यह परियोजना वर्तमान में केवल Firefox का समर्थन करती है
AlignDev

1
आखिरी बार 4 साल पहले, फ़ायरफ़ॉक्स 36 और फायरबग के बारे में बोलता है ... तब से कई चीजें बदल गईं।
Fla

और क्या यह इसके लिए मूल ब्लॉग पोस्ट है? mguillem.wordpress.com/2011/10/11/…
डेविड


3

मैं jhanifen के उत्तर पर पुनरावृति करना चाहूंगा। यहाँ एक जावास्क्रिप्ट समाधान है जो jQuery पर निर्भर नहीं करता है। यह पृष्ठ के निचले भाग पर एक अदृश्य HTML सूची बनाता है, जो त्रुटियों के बारे में बताता है।

(function () {
    var ul = null;
    function createErrorList() {
        ul = document.createElement('ul');
        ul.setAttribute('id', 'js_error_list');
        ul.style.display = 'none';
        document.body.appendChild(ul);
    }
    window.onerror = function(msg){
        if (ul === null)
            createErrorList();
        var li = document.createElement("li");
        li.appendChild(document.createTextNode(msg));
        ul.appendChild(li);
    };
})();

2

"Window.onerror" के साथ समाधान मेरे लिए काम नहीं किया।

इसलिए मैं उपयोगकर्ता-एक्सटेंशन्स को बदलने के साथ एक और समाधान बताना चाहता हूं। जेएस से मुझे मदद मिली:
यदि पेज में जावास्क्रिप्ट त्रुटियां हैं तो क्या सेलेनियम पता लगा सकता है?

मुख्य लाभ: आपको चेक करने के लिए पृष्ठ स्रोत को बदलना नहीं है ।

और यहां बताया गया है कि उपयोगकर्ता-एक्सटेंशन्स का उपयोग कैसे करें। जेएस:
सेलेनियम-आईडीई के साथ उपयोगकर्ता-एक्सटेंशन का उपयोग करना

नोट: यह समाधान केवल फ़ायरफ़ॉक्स के साथ काम करता है


2

यहाँ मेरा समाधान jhanifen की प्रतिक्रिया से प्रेरित है:

// common.js - js file common to the entire app
globalError = []
window.onerror = function (msg, url, line, col, error) {
    globalError.push({msg:msg, url:url, line:line})
};

# tests.py
def tearDown(driver):
    # assert on js error 
    ret = driver.selenium.execute_script("return globalError ")
    driver.assertFalse(ret, "errors %r " % ret)
    # ret will be a dict looking like 
    # {'line': 50, 'url': 'http://localhost:8081/static/js/common.js', 'msg': 'Uncaught ReferenceError: s is not defined'}

1

यदि आप जावा का उपयोग कर रहे हैं, तो मेरे द्वारा कॉम्युट किए गए इस पुस्तकालय को आज़माने के लिए आपका स्वागत है जो क्रोमेड्रिवर सत्र में प्राप्त जेएस त्रुटियों को आसानी से इकट्ठा करने की अनुमति देता है, परीक्षण विधियों पर एनोटेशन का उपयोग करते हुए। यह विस्तारित एनोटेशन के साथ JUnit5 पर, और एनोटेशन को पार्स करने वाले श्रोता के साथ TestNG पर काम करता है। एनोटेशन में बूलियन मूल्य होते हैं जो आपको यह तय करने देते हैं कि क्या आप परीक्षण के निष्पादन के बाद मिली त्रुटियों को दर्ज करना या लॉग इन करना चाहते हैं।

JUnit5 उदाहरण:

@Test
@JSErrorsCollectorJUnit
void referenceErrorTest(TestInfo testInfo) throws InterruptedException {

    // Create a new instance of ChromeDriver.
    driver = new ChromeDriver();

    // Set your test name to point its ChromeDriver session in HashMap.
    JSErrorsDriverHolder.setDriverForTest(testInfo.getDisplayName(), driver);

    // Navigate to URL.
    driver.get("http://testjs.site88.net");

    // The click on the button in the test site should cause JS reference error.
    driver.findElement(By.name("testClickButton")).click();
    waitBeforeClosingBrowser();
}

1

मैं TestCase.tearDown()अपने पायथन सेलेनियम परीक्षणों में निम्नलिखित का उपयोग करता हूं जो जावास्क्रिप्ट त्रुटियों के मामले में परीक्षण को विफल बनाता है:

def tearDown(self):
    browser_logs = driver.get_log("browser")
    errors = [logentry['message'] for logentry in browser_logs if logentry['level'] == 'SEVERE']
    if errors:
        self.fail(f'The following JavaScript errors occurred: {"; ".join(errors)}')

यह @kleptog और @ d3ming के उत्तरों से प्रेरित है।


0

आप अपने पेज में windows.onerror इवेंट को शामिल करने का प्रयास करते हैं या IE विकल्प में शो एरर डायलॉग बॉक्स को सक्षम करते हैं। यदि आप बाद में चुनते हैं तो Se1 हैंग हो जाएगा। पुनश्च: इस पर यहां चर्चा की गई है। एक खोज करते हैं।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.