2016-12-08 9 views
6

के आसपास निर्माण करता है I परीक्षण के लिए हास्केल वेबड्राइवर सेलेनियम पैकेज के माध्यम से काम कर रहा हूं, hereएक हैकेल "withSubprocess" एक ब्लॉक ब्लॉक

मैं इस उदाहरण है:

import Test.WebDriver 

firefoxConfig :: WDConfig 
firefoxConfig = defaultConfig 

main :: IO() 
main = runSession firefoxConfig $ do      
    openPage "http://google.com"        
    searchInput <- findElem (ByCSS "input[type='text']") 
    sendKeys "Hello, World!" searchInput      
    submit searchInput          
    closeSession            

getting started section स्पष्ट करता है कि सेलेनियम ग्राहक के बिना यह चल

java -jar selenium-server-standalone-*.jar 

के साथ संवाद करने के लिए एक सेलेनियम सर्वर की आवश्यकता है, तो आप इस मिल:

ghci λ> main 
*** Exception: FailedConnectionException2 "127.0.0.1" 4444 False connect: does not exist (Connection refused) 

मैं अपनी पूरी टेस्ट स्क्रिप्ट को ऐसे फ़ंक्शन में लपेटना चाहता हूं जो टी शुरू करता है सत्र चलाने के बाद वह सेलेनियम-सर्वर, अपने पिड रिकॉर्ड करता है, और मारता है (पिड)। यही है, मेरे मौजूदा मुख्य की अवधि के लिए, मैं जावा सेलेनियम-सर्वर को अस्तित्व में कॉल करना चाहता हूं, लेकिन जैसे ही कॉल समाप्त हो जाता है, मैं इसे मौजूदा रूप से रोकना चाहता हूं।

अजगर में मैं एक __enter__() और अन्य आंसू नीचे सामान के साथ एक __exit__(), subprocess.Popen को परिभाषित करने की तरह कुछ कर ऐसा करते हैं चाहते हैं, आईडी रिकॉर्ड करते हैं, यह मार, तो बुला

with Browser() as b: 
    do_stuff 

मैं समझ प्राप्त रनसेशन इकाई ऐसी चीज है जिसे मुझे स्टार्टअप और टियरडाउन को लपेटने के लिए दोहराने की आवश्यकता होगी, इस अर्थ में कि यह firefoxConfig $ do ब्लॉक को तर्क के रूप में लेता है और मैं भी ऐसा करना चाहता हूं। मुझे लगता है मैं withMonad किसी तरह मैं इस पर लागू हो सकते के लिए विचार करना होता

ghci λ> :t runSession 
runSession 
    :: Test.WebDriver.Config.WebDriverConfig conf => 
    conf -> WD a -> IO a 

:

हालांकि, मैं काफी runSession पूछताछ से प्रकार नहीं समझ सकता, कैसे बात इस तरह का बनाने के लिए जो do पर लागू होता है। मुझे लगता है कि वाक्य रचना के कुछ प्रकार होगा ...

import Test.WebDriver 
import System.Process 

firefoxConfig :: WDConfig 
firefoxConfig = defaultConfig 

withBrowser :: Monad a -> Monad a -- maybe this type? 
withBrowser = do 
    r <- createProcess (proc "java -jar selenium-server-standalone-*.jar" []) 
    -- other magic here? 

main :: IO() 
main = withBrowser $ runSession firefoxConfig $ do      
    openPage "http://google.com"        
    searchInput <- findElem (ByCSS "input[type='text']") 
    sendKeys "Hello, World!" searchInput      
    submit searchInput          
    closeSession            

मैं यह कैसे प्राप्त होगा? क्या मोनाद बिल्कुल सही है? क्या इसके लिए कोई और हास्केल मुहावरे या रणनीति है?

+1

एक 'मोनाद' एक प्रकार नहीं है। इसके अलावा, इसे आसान रखें। 'createProcess 'और' runSession' दोनों 'IO' का उपयोग करते हैं, इसलिए' IO' में रहें। 'ब्रोसर :: आईओ ए -> आईओ ए'। – Zeta

+0

शैल स्क्रिप्ट का उपयोग क्यों नहीं करें? – Ingo

उत्तर

1

आप मूल रूप से brackethttps://hackage.haskell.org/package/base-4.9.0.0/docs/Control-Exception.html#v:bracket से चाहते हैं।

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

कुछ की तरह:

withBrowser browserAction 
    = bracket startSelenium killSelenium (const browserAction) 

(मैं कहां से मान लिया गया है आप पीआईडी ​​के लिए एक तर्क ले जाना है करने के लिए मुख्य कार्रवाई नहीं करना चाहते हैं, तो मैं const इस्तेमाल किया यह अनदेखी करने के लिए)

+0

क्या वह ब्रैकेट_ है जो तर्क से बचने के लिए है? – Mittenchops

+1

@Mittenchops प्रारंभ में मैंने सोचा था कि आप यही चाहते हैं, लेकिन ध्यान दें कि सफाई कार्रवाई में कोई तर्क नहीं है। तो आपके पास स्टार्टअप एक्शन से क्लीनअप में पीआईडी ​​को परिवहन करने का कोई तरीका नहीं होगा (इसे आईओआरएफ या कुछ में चिपके बिना)। – Ben

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