Форум программистов, компьютерный форум, киберфорум
Haskell
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.50/6: Рейтинг темы: голосов - 6, средняя оценка - 4.50
97 / 78 / 12
Регистрация: 07.06.2015
Сообщений: 132
Записей в блоге: 12
1

Selenium+haskell

07.06.2015, 20:51. Показов 1196. Ответов 10
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Здравствуйте!
Появилось свободное время. Решил узнать, подойдет ли хаскелл для автотестов.
По логике моего автотеста, мне надо на странице http://www.etagi.com/zastr/?wh... ms%5B%5D=1
проверить, то в каждой таблице в колонке "Комнат", написано "1"
Вот код, который проходит до момента проверки:
Haskell
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
{-# LANGUAGE OverloadedStrings #-}
module Main where
 
import Test.WebDriver
 
myConfig :: WDConfig
myConfig = defaultConfig
 
main :: IO ()
main = runSession myConfig $ do
openPage "https://www.etagi.com/"
searchCount <- findElem $ ByClass "search_count"
searchCountText <- getText searchCount
-- TODO проверку, что  searchCountText >= 0
newBuild <- findElem (ByLinkText "НОВОСТРОЙКИ")
click newBuild
searchCount <- findElem (ByClass "search_count")
newBuildSearchCountText <- getText searchCount
-- TODO проверку, что  newBuildSearchCountText  >= 0
oneRoomFilter <- findElem (ByClass "room_check")
click oneRoomFilter
searchCount <- findElem (ByClass "search_count")
newBuildSearchCountTextNewState <- getText searchCount
-- TODO проверку, что  newBuildSearchCountText /= newBuildSearchCountTextNewState 
searchButton <- findElem (ByTag "BUTTON")
click searchButton
-- TODO проверить, что в каждой колонке столбца "Комнат", стоит 1
Подскажите пожалуйста, как вытащить все значения?
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
07.06.2015, 20:51
Ответы с готовыми решениями:

Место ФП и Haskell в компьютерной индустрии (Для чего он нужен, этот Haskell?)
&quot;У нас&quot; ? А где преподавание этой экзотики на высоте? Добавлено через 2 минуты А где такие...

HASKELL
Добрый вечер, прошу помощи у знающих Haskell, не понимаю его, не для меня видимо, но сдать...

Haskell return
привет! main:: String -&gt; IO main:: String -&gt; IO() main:: IO()

Условия в Haskell
Пожалуйста, помогите определить функцию sort3, по трём целым возвращающую отсортированный по...

10
Модератор
5047 / 3276 / 526
Регистрация: 01.06.2013
Сообщений: 6,806
Записей в блоге: 9
08.06.2015, 15:54 2
Цитата Сообщение от loothood Посмотреть сообщение
подойдет ли хаскелл для автотестов
Думаю, что нет. Попробовал поставить пакет WebDriver. После танцев с бубном (зависимые пакеты нужно отдельно устанавливать, со специальным ключём - известная бага новых cabal-ов), выяснилось, что сам пакет WebDriver не компилируется, ошибки. Думаю, что даже если у Вас linux, то и в нём так же будет.

При учёте того, что, Вы (мне так кажется по посту, может ошибаюсь) с Haskell раньше дело не имели (например, отсупы важны, их нельзя убирать), то, лучше попробовать клиента на другом языке.
0
97 / 78 / 12
Регистрация: 07.06.2015
Сообщений: 132
Записей в блоге: 12
08.06.2015, 17:04  [ТС] 3
Да на самом деле, все получилось. Весь сценарий работает. Только не могу проблему решить с которой и создал топик.
Я получил все таблицы со страницы.
Тип - Element, который наследуется от типа Text.
Вот первый элемент из списка типа [Elements]:
Haskell
1
2
3
4
5
6
7
8
9
"\1055\1086\1076\1098\1077\1079\1076 \1069\1090\1072\1078 \1050\1086\1084\1085\1072\1090 \1055\1083\1086\1097\1072\1076\1100, \1084\&2 \1055\1083\1086\1097\1072\1076\1100\n\1082\1091\1093\1085\1080, \1084\&2 \1057\1090\1086\1080\1084\1086\1089\1090\1100, \1088\1091\1073. \1062\1077\1085\1072\n\1079\1072 \1084\&2, \1088\1091\1073. \1042 \1080\1087\1086\1090\1077\1082\1091
\1086\1090 (\1088\1091\1073.):
2 14 1 41.7 0 2 900 000 69 544 23 663
2 12 1 41.7 0 2 900 000 69 544 23 663
3 14 1 48 14 3 740 000 77 917 30 517
2 11 1 41.8 0 2 900 000 69 378 23 663
3 13 1 48 14 3 740 000 77 917 30 517
2 10 1 41.8 0 2 900 000 69 378 23 663
2 9 1 41.8 0 2 900 000 69 378 23 663"
количество строк можно посчитать, считая количество символов переносов строки '\n'(странно почему они не отобразились их, они есть), осталось придумать как вытащить из каждой колонки "1" из третьего столбца и сравнить с количеством строк. Если будут идеи как, с радостью выслушаю.
Вы правы - хаскеле новичок - неделю программирую в свободное от работы время, но про отступы знаю. Почему-то в первом посту криво вставилось.
Вот полный листинг автотеста:
Haskell
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
{-# LANGUAGE OverloadedStrings #-}
module Main where
 
import Test.WebDriver
import Data.Text
import Control.Monad.IO.Class
import qualified Data.ByteString.Lazy.Char8 as B
 
screenshotWriteFile :: FilePath -> WD ()
screenshotWriteFile name = do
                                string <- screenshot
                                liftIO . B.writeFile name $ string
 
myConfig :: WDConfig
myConfig = defaultConfig
 
getNumber :: Text -> Int
getNumber text = read (Prelude.filter (\x -> x `elem` ['0'..'9']) (unpack text)) :: Int
 
countCheckStep :: (Num a, Ord a) => a -> String -> FilePath -> String -> WD ()
countCheckStep number messageFail filenameFail message  | number <= 0 = do 
                                                                            screenshotWriteFile filenameFail 
                                                                            fail messageFail
                                                        | otherwise = liftIO $ putStrLn message
 
main :: IO ()
main = runSession myConfig $ do
    openPage "https://www.etagi.com/"
    searchCount <- findElem $ ByClass "search_count"
    searchCountText <- getText searchCount
    countCheckStep (getNumber searchCountText) "Количество объектов меньше, либо равно нулю!" 
                    "failFirstStep.png" "Прошли первую проверку"
    newBuild <- findElem $ ByLinkText "НОВОСТРОЙКИ"
    click newBuild
    searchCount <- findElem $ ByClass "search_count"
    newBuildSearchCountText <- getText searchCount
    countCheckStep (getNumber newBuildSearchCountText) "Количество новостроек меньше, либо равно нулю" 
                    "failSecondStep.png" "Прошли вторую проверку"
    oneRoomFilter <- findElem $ ByClass "room_check"
    click oneRoomFilter 
    searchCount1 <- findElem $ ByCSS "#searcher > form > div > div.action_wrap.clearfix > p > span.search_count > b"
    newBuildSearchCountTextNewState <- getText searchCount1
    liftIO $ print newBuildSearchCountText
    liftIO $ print newBuildSearchCountTextNewState
    searchButton <- findElem $ ByTag "BUTTON"
    click searchButton
    allTablesElements <- findElems $ ByClass "newhouses_flats"
    liftIO $ print allTablesElements
    firstEl <- getText (Prelude.head allTablesElements)
    liftIO $ print (firstEl)
    investorsBuildsSpan <- findElem $ ByCSS "#objects > div.js-tabs.tabs.line1 > a > span"
    click investorsBuildsSpan
    investorsBuils <- findElems $ ByClass "title-obj"
    click investorsBuildsSpan
Так, же, если не затруднит, подскажите пожалуйста, как в хаскеле сделать sleep?
Пробовал так:
Haskell
1
2
3
import Control.Concurrent
....
threadDelay 100000
Получаю ошибку:
Haskell
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
    Couldn't match type `IO' with `WD'
    Expected type: WD ()
      Actual type: IO ()
    In a stmt of a 'do' block: threadDelay 100000
    In the second argument of `($)', namely
      `do { openPage "https://www.etagi.com/";
            searchCount <- findElem $ ByClass "search_count";
            searchCountText <- getText searchCount;
            countCheckStep
              (getNumber searchCountText)
              "\1050\1086\1083\1080\1095\1077\1089\1090\1074\1086 \1086\1073\1098\1077\1082\1090\1086\1074 \1084\1077\1085\1100\1096\1077, \1083\1080\1073\1086 \1088\1072\1074\1085\1086 \1085\1091\1083\1102!"
              "failFirstStep.png"
              "\1055\1088\1086\1096\1083\1080 \1087\1077\1088\1074\1091\1102 \1087\1088\1086\1074\1077\1088\1082\1091";
            .... }'
Failed, modules loaded: none.
Я так понимаю, надо каким-то образом из монады IO получить WD, но не знаю как
0
202 / 200 / 65
Регистрация: 06.10.2013
Сообщений: 552
08.06.2015, 18:13 4
Цитата Сообщение от loothood Посмотреть сообщение
как вытащить из каждой колонки "1" из третьего столбца
смотрите функции words (разбить строки на слова - получится список слов [String]), (!!) (вытащить энный элемент списка).

Цитата Сообщение от loothood Посмотреть сообщение
и сравнить с количеством строк.
функция lines

Добавлено через 18 минут
Цитата Сообщение от loothood Посмотреть сообщение
Я так понимаю, надо каким-то образом из монады IO получить WD, но не знаю как
Покажите ваш код с threadDelay
1
97 / 78 / 12
Регистрация: 07.06.2015
Сообщений: 132
Записей в блоге: 12
08.06.2015, 18:22  [ТС] 5
Вот с threadDelay
Haskell
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
{-# LANGUAGE OverloadedStrings #-}
module Main where
 
import Test.WebDriver
import Data.Text
import Control.Monad.IO.Class
import qualified Data.ByteString.Lazy.Char8 as B
import Control.Concurrent
 
substrings []     = []
substrings (x:xs) = substrings' (x:xs) ++ substrings xs where
  substrings' []     = []
  substrings' (y:ys) = [y] : [ (y:s) | s <- substrings' ys ]
 
screenshotWriteFile :: FilePath -> WD ()
screenshotWriteFile name = do
                                string <- screenshot
                                liftIO . B.writeFile name $ string
 
myConfig :: WDConfig
myConfig = defaultConfig
 
getNumber :: Text -> Int
getNumber text = read (Prelude.filter (\x -> x `elem` ['0'..'9']) (unpack text)) :: Int
 
countCheckStep :: (Num a, Ord a) => a -> String -> FilePath -> String -> WD ()
countCheckStep number messageFail filenameFail message  | number <= 0 = do 
                                                                            screenshotWriteFile filenameFail 
                                                                            fail messageFail
                                                        | otherwise = liftIO $ putStrLn message
 
main :: IO ()
main = runSession myConfig $ do
    openPage "https://www.etagi.com/"
    searchCount <- findElem $ ByClass "search_count"
    searchCountText <- getText searchCount
    countCheckStep (getNumber searchCountText) "Количество объектов меньше, либо равно нулю!" 
                    "failFirstStep.png" "Прошли первую проверку"
    newBuild <- findElem $ ByLinkText "НОВОСТРОЙКИ"
    click newBuild
    searchCount <- findElem $ ByClass "search_count"
    newBuildSearchCountText <- getText searchCount
    countCheckStep (getNumber newBuildSearchCountText) "Количество новостроек меньше, либо равно нулю" 
                    "failSecondStep.png" "Прошли вторую проверку"
    oneRoomFilter <- findElem $ ByClass "room_check"
    click oneRoomFilter 
    searchCount1 <- findElem $ ByCSS "#searcher > form > div > div.action_wrap.clearfix > p > span.search_count > b"
    newBuildSearchCountTextNewState <- getText searchCount1
    liftIO $ print newBuildSearchCountText
    liftIO $ print newBuildSearchCountTextNewState
    searchButton <- findElem $ ByTag "BUTTON"
    click searchButton
    threadDelay 100000
    allTablesElements <- findElems $ ByClass "newhouses_flats"
    investorsBuildsSpan <- findElem $ ByCSS "#objects > div.js-tabs.tabs.line1 > a > span"
    click investorsBuildsSpan
    investorsBuils <- findElems $ ByClass "title-obj"
    click investorsBuildsSpan
0
Модератор
5047 / 3276 / 526
Регистрация: 01.06.2013
Сообщений: 6,806
Записей в блоге: 9
08.06.2015, 19:34 6
Цитата Сообщение от loothood Посмотреть сообщение
Я так понимаю, надо каким-то образом из монады IO получить WD, но не знаю как
Так же, как и 30-ой строчке. Т.е. Вашу 53-ую заменяем на
Haskell
1
liftIO $ threadDelay 100000
Добавлено через 12 минут
... хотя, в пакете есть свои функции ожидания. Наверно, лучше ими воспользоваться.
Haskell
1
2
3
4
5
6
    waitUntil  1.0 $ do
        allTablesElements <- findElems $ ByClass "newhouses_flats"
        investorsBuildsSpan <- findElem $ ByCSS "#objects > div.js-tabs.tabs.line1 > a > span"
        click investorsBuildsSpan
        investorsBuils <- findElems $ ByClass "title-obj"
        click investorsBuildsSpan
- тайм-аут в 1 секунда. 0.1 секунда для интернета, мне кажется, маловато.

Добавлено через 28 минут
И пример проверки третьих элементов строк на равенство "1" с предварительным удалением первых двух строк.
Haskell
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
{-# LANGUAGE OverloadedStrings #-}
module Main where 
 
import qualified Data.Text as T
import Data.List (all)
 
testdata = 
   "aaaaaaaaaaaa\n\
   \bbbbbbbbbbbb :\n\
   \2 14 1 41.7 0 2 900 000 69 544 23 663\n\
   \2 12 1 41.7 0 2 900 000 69 544 23 663\n\
   \3 14 1 48 14 3 740 000 77 917 30 517\n\
   \2 11 1 41.8 0 2 900 000 69 378 23 663\n\
   \3 13 1 48 14 3 740 000 77 917 30 517\n\
   \2 10 1 41.8 0 2 900 000 69 378 23 663\n\
   \2 9 1 41.8 0 2 900 000 69 378 23 663"
 
check1:: T.Text -> Bool
check1 =   all ( ("1"==) . (!! 2)  . T.words) . drop 2 . T.lines    
 
main:: IO () 
main = print $ check1 testdata
0
97 / 78 / 12
Регистрация: 07.06.2015
Сообщений: 132
Записей в блоге: 12
08.06.2015, 19:37  [ТС] 7
Я видел эти функции. Дело в том, что мне надо ожидать java script событие, которое одно число меняет на другое. waitUntil будет ждать пока что-либо не произойдет типа перегарузки страницы или пока не прогрузиться какой-либо элемент, но у меня элемент уже прогрузился, потому этот метод упадет по таймауту. А про waitWhile - не будет ждать, так как элемент уже есть на странице и метод совершенно справедливо полагает, что ждать нечего.
По threadDelay спасибо. Помогло.

Добавлено через 2 минуты
Цитата Сообщение от KolodeznyDiver Посмотреть сообщение
И пример проверки третьих элементов строк на равенство "1" с предварительным удалением первых двух
Спасибо за метод. Я написал свой, основанный на разнице строк и найденных слов == " 1 ", но ваш гораздо лучше
0
Curry
08.06.2015, 19:48
  #8

Не по теме:

Цитата Сообщение от loothood Посмотреть сообщение
Вы правы - хаскеле новичок - неделю программирую в свободное от работы время
Выдающиеся успехи за неделю! :good:
На других функциональных языках раньше писали?

0
97 / 78 / 12
Регистрация: 07.06.2015
Сообщений: 132
Записей в блоге: 12
08.06.2015, 21:12  [ТС] 9
На swi prolog писал на протяжении шести месяцев.
Возник еще вопрос, который не могу понять:
Метод возвращает список элементов:
Haskell
1
2
3
4
5
*Main> :t findElems
findElems
  :: Test.WebDriver.Class.WebDriver wd => Selector -> wd [Element]
*Main> 
allTablesElements <- findElems $ ByClass "newhouses_flats"
Пишу методы для проверки, что во всех найденных таблицах третья колонка всегда равна 1:
Haskell
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
check1 :: Text -> Bool
check1 =  P.all ( ("1"==) . (!! 2)  . T.words) . P.drop 2 . T.lines  
 
checkOneTable :: Text -> WD ()
checkOneTable tableElement = if check1 tableElement == False then do 
                                                          screenshotWriteFile "123.png"
                                                          fail "Error" 
                                                     else
                                                          liftIO $ putStrLn "Good"
                                                          
checkFoundTables :: [Element] -> String                                                                    
checkFoundTables [] = ""
checkFoundTables (x:xs) = do 
                            s <- getText x
                            checkOneTable s
                            checkFoundTables xs
И вызываю:
Haskell
1
checkFoundTables allTablesElements
Получаю ошибку на строке
checkOneTable s:
Haskell
1
2
3
4
5
6
7
8
Couldn't match type `WD' with `[]'
    Expected type: [()]
      Actual type: WD ()
    In a stmt of a 'do' block: checkOneTable s
    In the expression:
      do { s <- getText x;
           checkOneTable s;
           checkFoundTables xs }
и на строке вызова checkFoundTables allTablesElements
Haskell
1
2
3
4
5
6
7
8
9
10
11
12
13
Couldn't match type `[]' with `WD'
Expected type: WD Char
  Actual type: String
In a stmt of a 'do' block: checkFoundTables allTablesElements
In the second argument of `($)', namely
  `do { openPage "https://www.etagi.com/";
...
checkFoundTables allTablesElements;
        investorsBuildsSpan <- findElem
                               $ ByCSS "#objects > div.js-tabs.tabs.line1 > a > span";
        click investorsBuildsSpan;
        investorsBuils <- findElems $ ByClass "title-obj";
        click investorsBuildsSpan }'
Подскажите куда копать? не понимаю как правильно объявить функции.
Или можно что мне прочесть, чтобы так сильно не просаживаться при объявлении типов с которыми функции работают?
Если нужен полный код:
Haskell
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
{-# LANGUAGE OverloadedStrings #-}
module Main where
 
import Prelude as P
import Test.WebDriver
import Data.Text as T
import Control.Monad.IO.Class
import qualified Data.ByteString.Lazy.Char8 as B
import Control.Concurrent
 
screenshotWriteFile :: FilePath -> WD ()
screenshotWriteFile name = do
                                string <- screenshot
                                liftIO . B.writeFile name $ string
 
myConfig :: WDConfig
myConfig = defaultConfig
 
getNumber :: Text -> Int
getNumber text = read (P.filter (\x -> x `elem` ['0'..'9']) (unpack text)) :: Int
 
countCheckStep :: (Num a, Ord a) => a -> String -> FilePath -> String -> WD ()
countCheckStep number messageFail filenameFail message  | number <= 0 = do 
                                                                            screenshotWriteFile filenameFail 
                                                                            fail messageFail
                                                        | otherwise = liftIO $ putStrLn message
 
check1 :: Text -> Bool
check1 =  P.all ( ("1"==) . (!! 2)  . T.words) . P.drop 4 . T.lines  
 
checkOneTable :: Text -> WD ()
checkOneTable tableElement = if check1 tableElement == False then do 
                                                          screenshotWriteFile "123.png"
                                                          fail "Error" 
                                                     else
                                                          liftIO $ putStrLn "Good"
                                                          
checkFoundTables :: [Element] -> String                                                                    
checkFoundTables [] = "Good"
checkFoundTables (x:xs) = do 
                            s <- getText x
                            checkOneTable s
                            checkFoundTables xs
                            
main :: IO ()
main = runSession myConfig $ do
    openPage "https://www.etagi.com/"
    searchCount <- findElem $ ByClass "search_count"
    searchCountText <- getText searchCount
    countCheckStep (getNumber searchCountText) "Количество объектов меньше, либо равно нулю!" 
                    "failFirstStep.png" "Прошли первую проверку"
    newBuild <- findElem $ ByLinkText "НОВОСТРОЙКИ"
    click newBuild
    searchCount <- findElem $ ByClass "search_count"
    newBuildSearchCountText <- getText searchCount
    countCheckStep (getNumber newBuildSearchCountText) "Количество новостроек меньше, либо равно нулю" 
                    "failSecondStep.png" "Прошли вторую проверку"
    oneRoomFilter <- findElem $ ByClass "room_check"
    click oneRoomFilter 
    liftIO $ threadDelay 1000000
    searchCount <- findElem $ ByClass "search_count"
    newBuildSearchCountTextNewState <- getText searchCount
    countCheckStep (getNumber newBuildSearchCountText -
                    getNumber newBuildSearchCountTextNewState) 
                    "Количество новостроек не изменилось после выбора однокомнатных квартир, либо их стало меньше!" 
                    "failThirdStep.png" "Прошли третью проверку"
    liftIO $ print newBuildSearchCountText
    liftIO $ print newBuildSearchCountTextNewState
    searchButton <- findElem $ ByTag "BUTTON"
    click searchButton
    allTablesElements <- findElems $ ByClass "newhouses_flats"
    firstEl <- getText $ P.head allTablesElements
    checkOneTable firstEl
    checkFoundTables allTablesElements
    investorsBuildsSpan <- findElem $ ByCSS "#objects > div.js-tabs.tabs.line1 > a > span"
    click investorsBuildsSpan
    investorsBuils <- findElems $ ByClass "title-obj"
    
    click investorsBuildsSpan
0
Модератор
5047 / 3276 / 526
Регистрация: 01.06.2013
Сообщений: 6,806
Записей в блоге: 9
08.06.2015, 22:10 10
С отступами аккуратнее! if, особенно если будет внутри do, так then и else лучше пусть начинаться с одной колонки, которая правее чем if, а выражения в них ещё правее, и тоже, с одной колонки начинать.
Но, тут удобнее охранное выражение использовать
Haskell
1
2
3
4
5
6
checkOneTable :: Text -> WD ()
checkOneTable tableElement 
    | check1 tableElement = liftIO $ putStrLn "Good"
    | otherwise = do 
                          screenshotWriteFile "123.png"
                          fail "Error"
К, сожалению, у себя проверить пока не могу. Ещё не разобрался почему не компилируется пакет WebDriver.
Цитата Сообщение от loothood Посмотреть сообщение
Получаю ошибку на строке
checkOneTable s
Функция checkFoundTables возвращает строку которая всегда была бы "Good" и не использовалась. Она должна возвращать ничего (). А, поскольку, она использует монаду WD и вызывается из под монады WD, то её результат должен быть обёрнут в эту монаду. Добавляете
Haskell
1
import Control.Monad
и
Haskell
1
2
3
4
5
6
checkFoundTables :: [Element] -> WD ()
checkFoundTables [] = void
checkFoundTables (x:xs) = do 
                            s <- getText x
                            checkOneTable s
                            checkFoundTables xs
Но, короче будет
Haskell
1
2
3
4
checkFoundTables :: [Element] -> WD ()
checkFoundTables = mapM_ (\x -> do 
                                    s <- getText x
                                    checkOneTable s  )
0
97 / 78 / 12
Регистрация: 07.06.2015
Сообщений: 132
Записей в блоге: 12
09.06.2015, 12:49  [ТС] 11
Спасибо. Понял куда копать. Во всем разобрался.

Добавлено через 40 минут
На самом деле, ожидал что будет хуже.
А получилось что хаскелл+селениум не сложнее ява+селениум.
К сожалению, очень мало методов для работы с js событиями.
+ довольно сложно получить индетификатор поп-ап окна(я не стал заморачиваться и просто получал список всех окон и брал последнее из списка).
0
09.06.2015, 12:49
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
09.06.2015, 12:49
Помогаю со студенческими работами здесь

О Haskell по-человечески
Первое издание этой книги было опубликовано 5 марта 2014 года, о чём Денис Шевченко — её автор...

Template Haskell
Как переписать этот код с помощью цитирующих скобок... заранее спасибо. fstN :: Int -&gt; Q Exp fstN...

Сервер на Haskell
Здравствуйте. Захотелось написать небольшую серверную программу на Haskell. До этого писал...

Conduit Haskell
В общем занимаюсь реализацией AES. Написал код для 128-битного шифра. Пришла идея реализовать...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
11
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru