2017-09-13 27 views
9

के साथ अजीब टाइमआउट मैं स्कैलास्टेस्ट के सेलेनियम डीएसएल के साथ सेलेनियम परीक्षण लिख रहा हूं और मैं समय-समय पर चल रहा हूं जिसे मैं समझा नहीं सकता। मामलों को और अधिक जटिल बनाने के लिए, वे केवल कुछ समय लगते हैं।स्कैलाटेस्ट के सेलेनियम डीएसएल

समस्या तब होती है जब भी मैं किसी पृष्ठ लोड या कुछ जावास्क्रिप्ट प्रतिपादन के बाद तत्व का उपयोग करता हूं। यह इस तरह दिखता है:

click on "editEmployee" 
eventually { 
    textField(name("firstName")).value = "Steve" 
} 

मेरे PatienceConfig इस तरह कॉन्फ़िगर किया गया है:

override implicit val patienceConfig: PatienceConfig = 
    PatienceConfig(timeout = Span(5, Seconds), interval = Span(50, Millis)) 

परीक्षण निम्न त्रुटि के साथ विफल:

- should not display the old data after an employee was edited *** FAILED *** 
    The code passed to eventually never returned normally. Attempted 1 times over 10.023253653000001 seconds. 
    Last failure message: WebElement 'firstName' not found.. (EditOwnerTest.scala:24) 

यह भावना है कि यह सफल नहीं होता बनाता है तत्काल, क्योंकि click कुछ प्रतिपादन का कारण बनता है, और टेक्स्टफील्ड तुरंत उपलब्ध नहीं हो सकता है। हालांकि, इसे खोजने का प्रयास करने में 10 सेकंड नहीं लगना चाहिए, है ना?

इसके अलावा, मुझे यह बहुत दिलचस्प लगता है कि आखिरकार ब्लॉक ने इसे केवल एक बार कोशिश की, और यह लगभग 10 सेकंड लग गया। यह एक समय सीमा की तरह गंध करता है, और यह मेरी धैर्य कॉनफिग नहीं है, क्योंकि यह 5 सेकंड के बाद समय पर सेट हो गया था।

इस समाधान के साथ

, यह करता है काम:

click on "editEmployee" 
eventually { 
    find(name("firstName")).value // from ScalaTest's `OptionValues` 
} 
textField(name("firstName")).value = "Steve" 

मैं कुछ ScalaTest स्रोत में खुदाई, और मैंने देखा है कि सभी कॉल है कि इस समस्या है (यह सिर्फ textField नहीं है), अंततः webElement फोन किया था किन्हीं बिंदुओं पर। वर्कअराउंड काम करने का कारण यह है कि यह webElement पर कॉल नहीं करता है। webElement इस तरह परिभाषित किया गया है:

def webElement(implicit driver: WebDriver, pos: source.Position = implicitly[source.Position]): WebElement = { 
    try { 
    driver.findElement(by) 
    } 
    catch { 
    case e: org.openqa.selenium.NoSuchElementException => 
     // the following is avoid the suite instance to be bound/dragged into the messageFun, which can cause serialization problem. 
     val queryStringValue = queryString 
     throw new TestFailedException(
       (_: StackDepthException) => Some("WebElement '" + queryStringValue + "' not found."), 
       Some(e), 
       pos 
       ) 
    } 
} 

मैं अपने प्रोजेक्ट में है कि कोड की नकल की है और इसके साथ चारों ओर खेला है, और यह निर्माण और/या फेंक जहां 10 सेकंड के सबसे बिताया रहे हैं अपवाद नहीं है की तरह लग रहा है।

(संपादित स्पष्टीकरण:। मैं वास्तव में देखा है कोड वास्तव में कैच ब्लॉक के अंदर अपनी 10 सेकंड खर्च निहित प्रतीक्षा 0 पर सेट है, और इसके अलावा, अगर मैं सब कुछ बस उम्मीद रूप में काम करता ब्लॉक पकड़ को हटा दें।)

तो मेरा सवाल यह है कि, मैं इस अजीब व्यवहार से बचने के लिए क्या कर सकता हूं? मैं हर समय find पर अनावश्यक कॉल डालना नहीं चाहता, क्योंकि यह आसानी से भूल जाता है, खासकर जब से मैंने कहा, त्रुटि केवल कुछ समय होती है। (मैं जब व्यवहार होता है निर्धारित करने में सक्षम नहीं है और नहीं किया गया है जब यह होता है।)

+0

क्या समय समाप्ति होने पर पृष्ठ अभी भी लोड हो रहा है? क्या आपने ब्राउज़र कंसोल की जांच की है कि क्या कोई त्रुटि है या नहीं? मेरा अनुमान है कि पृष्ठ में एक संसाधन है जो लोड करने में विफल रहा है, इस प्रकार पृष्ठ को ड्राइवर द्वारा अपेक्षित 'पूर्ण' स्थिति तक पहुंचने से रोकता है। –

+0

लेकिन यदि मामला भी है, तो 'driver.findElement' कॉल केवल असफल होनी चाहिए (क्योंकि निहित प्रतीक्षा 0 पर सेट है), इसे कैच ब्लॉक पर जाना चाहिए, और फिर 'अंततः' इसे फिर से प्रयास करेगा, है ना? – jqno

+0

निहित प्रतीक्षा सेटिंग का कोई प्रभाव नहीं पड़ता है और पृष्ठ को पूरा होने के इंतजार से संबंधित नहीं है। चालक प्रत्येक आदेश पर पृष्ठ [पूर्ण राज्य] (https://developer.mozilla.org/en-US/docs/Web/API/Document/readyState) के लिए प्रतीक्षा करता है जब तक कि क्षमता 'पृष्ठ लोडिंगस्ट्रेटी' को 'none' पर सेट न किया जाए । –

उत्तर

1

यह स्पष्ट है कि textField(name("firstName")).value = "Steve"WebElement को कॉल करने के बाद समाप्त होता है जैसा आपने पाया है। चूंकि ओप में समस्या हो रही है, जहां कभी भी वेब तत्व शामिल होते हैं (जो बदले में वेबड्राइवर शामिल है), मुझे लगता है कि यह मानना ​​सुरक्षित है कि यह समस्या वेब ड्राइवर पर निहित प्रतीक्षा से संबंधित है।

implicitlyWait(Span(0, Seconds)) 

उपरोक्त मुद्दे को आदर्श रूप से ठीक करना चाहिए। इसके अलावा, 0 होने का निहित इंतजार करना एक बुरा अभ्यास है। किसी भी वेब पेज में कुछ लोडिंग समस्या हो सकती है। पेज लोड को सेलेनियम द्वारा इसकी प्रतीक्षा स्थितियों के बाहर संभाला जाता है। लेकिन धीमी तत्व लोड (AJAX कॉल के कारण हो सकता है) विफलता के परिणामस्वरूप हो सकता है। मैं आमतौर पर अपने मानक निहित प्रतीक्षा के रूप में 10 सेकंड रखता हूं। उन परिदृश्यों के लिए जिनके लिए अधिक प्रतीक्षा की आवश्यकता है, स्पष्ट प्रतीक्षा का उपयोग किया जा सकता है।

def implicitlyWait(timeout: Span)(implicit driver: WebDriver): Unit = { 
driver.manage.timeouts.implicitlyWait(timeout.totalNanos, TimeUnit.NANOSECONDS) 
} 

निष्पादन प्रवाह:

name("firstName")Query {Val by = By.className("firstName") } के रूप में मूल्य होने समाप्त होता है।

def name(elementName: String): NameQuery = new NameQuery(elementName) 

case class NameQuery(queryString: String) extends Query { val by = By.name(queryString) } 

QuerytextField तरीका है जिसके नीचे के रूप में Query.webElement कॉल करने के लिए तंग आ गया है।

def textField(query: Query)(implicit driver: WebDriver, pos: source.Position): TextField = new TextField(query.webElement)(pos) 

sealed trait Query extends Product with Serializable { 

    val by: By 

    val queryString: String 

    def webElement(implicit driver: WebDriver, pos: source.Position = implicitly[source.Position]): WebElement = { 
     try { 
     driver.findElement(by) 
     } 
     catch { 
     case e: org.openqa.selenium.NoSuchElementException => 
      // the following is avoid the suite instance to be bound/dragged into the messageFun, which can cause serialization problem. 
      val queryStringValue = queryString 
      throw new TestFailedException(
        (_: StackDepthException) => Some("WebElement '" + queryStringValue + "' not found."), 
        Some(e), 
        pos 
        ) 
     } 
    } 
    } 
+0

'implicitlyWait' टाइमआउट बढ़ाने से मदद मिलती है! धन्यवाद! अफसोस की बात है कि बकाया राशि समाप्त होने से पहले मैं इस जवाब में शामिल नहीं था। – jqno

0

मैं ScalaTest की बारीकियों पता नहीं है, लेकिन इस तरह के अजीब समय समाप्ति आमतौर पर तब होता है जब आप एक साथ अंतर्निहित और स्पष्ट प्रतीक्षा करता है अप मिश्रण कर रहे हैं ।

driver.findElement निहित आंतरिक रूप से प्रतीक्षा करता है। और निर्दिष्ट स्पष्ट समय सीमा के आधार पर, आप दोनों को एक साथ जोड़कर सामना कर सकते हैं।

आदर्श रूप से, ऐसे मुद्दों से बचने के लिए अंतर्निहित प्रतीक्षा 0 पर सेट की जानी चाहिए।

+0

सुझाव के लिए धन्यवाद, लेकिन मैंने पहले से ही 0. – jqno

+0

होने का निहित इंतजार कॉन्फ़िगर किया था स्पष्ट तत्व का उपयोग करें जो तत्व को क्लिक करने योग्य होने की प्रतीक्षा करेगा। –

संबंधित मुद्दे