initial commit
11
.editorconfig
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
# EditorConfig is awesome: http://EditorConfig.org
|
||||||
|
|
||||||
|
root = true
|
||||||
|
|
||||||
|
[*]
|
||||||
|
indent_style = space
|
||||||
|
indent_size = 4
|
||||||
|
end_of_line = lf
|
||||||
|
insert_final_newline = true
|
||||||
|
charset = utf-8
|
||||||
|
trim_trailing_whitespace = true
|
||||||
3
.gitignore
vendored
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
venv
|
||||||
|
.idea
|
||||||
|
__pycache__
|
||||||
37
allure-report/app.js
Normal file
BIN
allure-report/data/attachments/15b144bb82e16a13.png
Normal file
|
After Width: | Height: | Size: 62 KiB |
BIN
allure-report/data/attachments/43262d127c532fc2.png
Normal file
|
After Width: | Height: | Size: 5.5 KiB |
41
allure-report/data/attachments/6f4fd4816dedd724.txt
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
INFO root:screenshots.py:103 Try make screenshots. Attempts: 0
|
||||||
|
INFO root:screenshots.py:32 Scroll to «window.scrollTo(0, 0)»
|
||||||
|
INFO root:screenshots.py:32 Scroll to «window.scrollTo(0, 600)»
|
||||||
|
INFO root:screenshots.py:32 Scroll to «window.scrollTo(0, 1200)»
|
||||||
|
INFO root:screenshots.py:32 Scroll to «window.scrollTo(0, 1800)»
|
||||||
|
INFO root:screenshots.py:32 Scroll to «window.scrollTo(0, 2400)»
|
||||||
|
INFO root:screenshots.py:32 Scroll to «window.scrollTo(0, 3000)»
|
||||||
|
INFO root:screenshots.py:32 Scroll to «window.scrollTo(0, 3600)»
|
||||||
|
INFO root:screenshots.py:32 Scroll to «window.scrollTo(0, 4200)»
|
||||||
|
INFO root:screenshots.py:32 Scroll to «window.scrollTo(0, 4800)»
|
||||||
|
INFO root:image_processor.py:101 Screen size: (1600, 9600)
|
||||||
|
INFO root:image_processor.py:105 Image added, offset is 0
|
||||||
|
INFO root:image_processor.py:105 Image added, offset is 1200
|
||||||
|
INFO root:image_processor.py:105 Image added, offset is 2400
|
||||||
|
INFO root:image_processor.py:105 Image added, offset is 3600
|
||||||
|
INFO root:image_processor.py:105 Image added, offset is 4800
|
||||||
|
INFO root:image_processor.py:105 Image added, offset is 6000
|
||||||
|
INFO root:image_processor.py:105 Image added, offset is 7200
|
||||||
|
INFO root:image_processor.py:105 Image added, offset is 8400
|
||||||
|
INFO root:screenshots.py:75 element: .search2, coordinates: (366, 542, 1570, 614)
|
||||||
|
INFO root:screenshots.py:32 Scroll to «window.scrollTo(0, 0)»
|
||||||
|
INFO root:screenshots.py:32 Scroll to «window.scrollTo(0, 600)»
|
||||||
|
INFO root:screenshots.py:32 Scroll to «window.scrollTo(0, 1200)»
|
||||||
|
INFO root:screenshots.py:32 Scroll to «window.scrollTo(0, 1800)»
|
||||||
|
INFO root:screenshots.py:32 Scroll to «window.scrollTo(0, 2400)»
|
||||||
|
INFO root:screenshots.py:32 Scroll to «window.scrollTo(0, 3000)»
|
||||||
|
INFO root:screenshots.py:32 Scroll to «window.scrollTo(0, 3600)»
|
||||||
|
INFO root:screenshots.py:32 Scroll to «window.scrollTo(0, 4200)»
|
||||||
|
INFO root:screenshots.py:32 Scroll to «window.scrollTo(0, 4800)»
|
||||||
|
INFO root:image_processor.py:101 Screen size: (1600, 9600)
|
||||||
|
INFO root:image_processor.py:105 Image added, offset is 0
|
||||||
|
INFO root:image_processor.py:105 Image added, offset is 1200
|
||||||
|
INFO root:image_processor.py:105 Image added, offset is 2400
|
||||||
|
INFO root:image_processor.py:105 Image added, offset is 3600
|
||||||
|
INFO root:image_processor.py:105 Image added, offset is 4800
|
||||||
|
INFO root:image_processor.py:105 Image added, offset is 6000
|
||||||
|
INFO root:image_processor.py:105 Image added, offset is 7200
|
||||||
|
INFO root:image_processor.py:105 Image added, offset is 8400
|
||||||
|
INFO root:screenshots.py:75 element: .search2, coordinates: (366, 544, 1570, 616)
|
||||||
|
INFO root:screenshots.py:122 Coords test: (366, 542, 1570, 614), coords prod: (366, 544, 1570, 616)
|
||||||
|
INFO root:screenshots.py:123 Size test: 1206, size prod: 1206
|
||||||
1
allure-report/data/attachments/7c5f405b92682e2f.uri
Normal file
@@ -0,0 +1 @@
|
|||||||
|
https://yandex.ru/
|
||||||
BIN
allure-report/data/attachments/8f9801e50746a9d2.png
Normal file
|
After Width: | Height: | Size: 62 KiB |
BIN
allure-report/data/attachments/ae0890108418dd6e.png
Normal file
|
After Width: | Height: | Size: 62 KiB |
45
allure-report/data/attachments/d77bd5a097581fae.txt
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
INFO root:screenshots.py:103 Try make screenshots. Attempts: 0
|
||||||
|
INFO root:screenshots.py:32 Scroll to «window.scrollTo(0, 0)»
|
||||||
|
INFO root:screenshots.py:32 Scroll to «window.scrollTo(0, 600)»
|
||||||
|
INFO root:screenshots.py:32 Scroll to «window.scrollTo(0, 1200)»
|
||||||
|
INFO root:screenshots.py:32 Scroll to «window.scrollTo(0, 1800)»
|
||||||
|
INFO root:screenshots.py:32 Scroll to «window.scrollTo(0, 2400)»
|
||||||
|
INFO root:screenshots.py:32 Scroll to «window.scrollTo(0, 3000)»
|
||||||
|
INFO root:screenshots.py:32 Scroll to «window.scrollTo(0, 3600)»
|
||||||
|
INFO root:screenshots.py:32 Scroll to «window.scrollTo(0, 4200)»
|
||||||
|
INFO root:screenshots.py:32 Scroll to «window.scrollTo(0, 4800)»
|
||||||
|
INFO root:screenshots.py:32 Scroll to «window.scrollTo(0, 5400)»
|
||||||
|
INFO root:image_processor.py:101 Screen size: (1600, 10800)
|
||||||
|
INFO root:image_processor.py:105 Image added, offset is 0
|
||||||
|
INFO root:image_processor.py:105 Image added, offset is 1200
|
||||||
|
INFO root:image_processor.py:105 Image added, offset is 2400
|
||||||
|
INFO root:image_processor.py:105 Image added, offset is 3600
|
||||||
|
INFO root:image_processor.py:105 Image added, offset is 4800
|
||||||
|
INFO root:image_processor.py:105 Image added, offset is 6000
|
||||||
|
INFO root:image_processor.py:105 Image added, offset is 7200
|
||||||
|
INFO root:image_processor.py:105 Image added, offset is 8400
|
||||||
|
INFO root:image_processor.py:105 Image added, offset is 9600
|
||||||
|
INFO root:screenshots.py:75 element: .news__header, coordinates: (24, 104, 1082, 412)
|
||||||
|
INFO root:screenshots.py:32 Scroll to «window.scrollTo(0, 0)»
|
||||||
|
INFO root:screenshots.py:32 Scroll to «window.scrollTo(0, 600)»
|
||||||
|
INFO root:screenshots.py:32 Scroll to «window.scrollTo(0, 1200)»
|
||||||
|
INFO root:screenshots.py:32 Scroll to «window.scrollTo(0, 1800)»
|
||||||
|
INFO root:screenshots.py:32 Scroll to «window.scrollTo(0, 2400)»
|
||||||
|
INFO root:screenshots.py:32 Scroll to «window.scrollTo(0, 3000)»
|
||||||
|
INFO root:screenshots.py:32 Scroll to «window.scrollTo(0, 3600)»
|
||||||
|
INFO root:screenshots.py:32 Scroll to «window.scrollTo(0, 4200)»
|
||||||
|
INFO root:screenshots.py:32 Scroll to «window.scrollTo(0, 4800)»
|
||||||
|
INFO root:screenshots.py:32 Scroll to «window.scrollTo(0, 5400)»
|
||||||
|
INFO root:image_processor.py:101 Screen size: (1600, 10800)
|
||||||
|
INFO root:image_processor.py:105 Image added, offset is 0
|
||||||
|
INFO root:image_processor.py:105 Image added, offset is 1200
|
||||||
|
INFO root:image_processor.py:105 Image added, offset is 2400
|
||||||
|
INFO root:image_processor.py:105 Image added, offset is 3600
|
||||||
|
INFO root:image_processor.py:105 Image added, offset is 4800
|
||||||
|
INFO root:image_processor.py:105 Image added, offset is 6000
|
||||||
|
INFO root:image_processor.py:105 Image added, offset is 7200
|
||||||
|
INFO root:image_processor.py:105 Image added, offset is 8400
|
||||||
|
INFO root:image_processor.py:105 Image added, offset is 9600
|
||||||
|
INFO root:screenshots.py:75 element: .news__header, coordinates: (24, 104, 1082, 412)
|
||||||
|
INFO root:screenshots.py:122 Coords test: (24, 104, 1082, 412), coords prod: (24, 104, 1082, 412)
|
||||||
|
INFO root:screenshots.py:123 Size test: 1102, size prod: 1102
|
||||||
BIN
allure-report/data/attachments/d807dd446712ec34.png
Normal file
|
After Width: | Height: | Size: 5.7 KiB |
BIN
allure-report/data/attachments/e4728e62a9273013.png
Normal file
|
After Width: | Height: | Size: 5.7 KiB |
1
allure-report/data/attachments/f764d0c1f0c002e8.uri
Normal file
@@ -0,0 +1 @@
|
|||||||
|
https://yandex.ru/
|
||||||
2
allure-report/data/behaviors.csv
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
"Epic","Feature","Story","FAILED","BROKEN","PASSED","SKIPPED","UNKNOWN"
|
||||||
|
"","","","2","0","0","0","0"
|
||||||
|
29
allure-report/data/behaviors.json
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
{
|
||||||
|
"uid" : "b1a8273437954620fa374b796ffaacdd",
|
||||||
|
"name" : "behaviors",
|
||||||
|
"children" : [ {
|
||||||
|
"name" : "test_search_field",
|
||||||
|
"uid" : "ff3cf8e351b44c24",
|
||||||
|
"parentUid" : "b1a8273437954620fa374b796ffaacdd",
|
||||||
|
"status" : "failed",
|
||||||
|
"time" : {
|
||||||
|
"start" : 1569176221591,
|
||||||
|
"stop" : 1569176247587,
|
||||||
|
"duration" : 25996
|
||||||
|
},
|
||||||
|
"flaky" : false,
|
||||||
|
"parameters" : [ ]
|
||||||
|
}, {
|
||||||
|
"name" : "test_news_widget",
|
||||||
|
"uid" : "35bf2eac0f3b5d9d",
|
||||||
|
"parentUid" : "b1a8273437954620fa374b796ffaacdd",
|
||||||
|
"status" : "failed",
|
||||||
|
"time" : {
|
||||||
|
"start" : 1569176222538,
|
||||||
|
"stop" : 1569176250120,
|
||||||
|
"duration" : 27582
|
||||||
|
},
|
||||||
|
"flaky" : false,
|
||||||
|
"parameters" : [ ]
|
||||||
|
} ]
|
||||||
|
}
|
||||||
2
allure-report/data/categories.csv
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
"Category","FAILED","BROKEN","PASSED","SKIPPED","UNKNOWN"
|
||||||
|
"Product defects","2","0","0","0","0"
|
||||||
|
41
allure-report/data/categories.json
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
{
|
||||||
|
"uid" : "4b4757e66a1912dae1a509f688f20b0f",
|
||||||
|
"name" : "categories",
|
||||||
|
"children" : [ {
|
||||||
|
"name" : "Product defects",
|
||||||
|
"children" : [ {
|
||||||
|
"name" : "AssertionError: «Поисковый блок» отличается на страницах:\nhttps://yandex.ru/\nи\nhttps://yandex.ru/",
|
||||||
|
"children" : [ {
|
||||||
|
"name" : "test_search_field",
|
||||||
|
"uid" : "ff3cf8e351b44c24",
|
||||||
|
"parentUid" : "21cceaf81a44534c14791402ab60e7a0",
|
||||||
|
"status" : "failed",
|
||||||
|
"time" : {
|
||||||
|
"start" : 1569176221591,
|
||||||
|
"stop" : 1569176247587,
|
||||||
|
"duration" : 25996
|
||||||
|
},
|
||||||
|
"flaky" : false,
|
||||||
|
"parameters" : [ ]
|
||||||
|
} ],
|
||||||
|
"uid" : "21cceaf81a44534c14791402ab60e7a0"
|
||||||
|
}, {
|
||||||
|
"name" : "AssertionError: «Хэдер с новостями» отличается на страницах:\nhttps://yandex.ru/\nи\nhttps://yandex.ru/",
|
||||||
|
"children" : [ {
|
||||||
|
"name" : "test_news_widget",
|
||||||
|
"uid" : "35bf2eac0f3b5d9d",
|
||||||
|
"parentUid" : "3095de4d040f98faf6d1c7fbdd61b3ce",
|
||||||
|
"status" : "failed",
|
||||||
|
"time" : {
|
||||||
|
"start" : 1569176222538,
|
||||||
|
"stop" : 1569176250120,
|
||||||
|
"duration" : 27582
|
||||||
|
},
|
||||||
|
"flaky" : false,
|
||||||
|
"parameters" : [ ]
|
||||||
|
} ],
|
||||||
|
"uid" : "3095de4d040f98faf6d1c7fbdd61b3ce"
|
||||||
|
} ],
|
||||||
|
"uid" : "8fb3a91ba5aaf9de24cc8a92edc82b5d"
|
||||||
|
} ]
|
||||||
|
}
|
||||||
33
allure-report/data/packages.json
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
{
|
||||||
|
"uid" : "83edc06c07f9ae9e47eb6dd1b683e4e2",
|
||||||
|
"name" : "packages",
|
||||||
|
"children" : [ {
|
||||||
|
"name" : "screenshot_tests.tests.yandex_main_page_test",
|
||||||
|
"children" : [ {
|
||||||
|
"name" : "test_search_field",
|
||||||
|
"uid" : "ff3cf8e351b44c24",
|
||||||
|
"parentUid" : "4a62f88a06567bac990f04c32bc01572",
|
||||||
|
"status" : "failed",
|
||||||
|
"time" : {
|
||||||
|
"start" : 1569176221591,
|
||||||
|
"stop" : 1569176247587,
|
||||||
|
"duration" : 25996
|
||||||
|
},
|
||||||
|
"flaky" : false,
|
||||||
|
"parameters" : [ ]
|
||||||
|
}, {
|
||||||
|
"name" : "test_news_widget",
|
||||||
|
"uid" : "35bf2eac0f3b5d9d",
|
||||||
|
"parentUid" : "4a62f88a06567bac990f04c32bc01572",
|
||||||
|
"status" : "failed",
|
||||||
|
"time" : {
|
||||||
|
"start" : 1569176222538,
|
||||||
|
"stop" : 1569176250120,
|
||||||
|
"duration" : 27582
|
||||||
|
},
|
||||||
|
"flaky" : false,
|
||||||
|
"parameters" : [ ]
|
||||||
|
} ],
|
||||||
|
"uid" : "screenshot_tests.tests.yandex_main_page_test"
|
||||||
|
} ]
|
||||||
|
}
|
||||||
3
allure-report/data/suites.csv
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
"Status","Start Time","Stop Time","Duration in ms","Parent Suite","Suite","Sub Suite","Test Class","Test Method","Name","Description"
|
||||||
|
"failed","Sun Sep 22 21:17:01 MSK 2019","Sun Sep 22 21:17:27 MSK 2019","25996","screenshot_tests.tests","yandex_main_page_test","TestYandexMainPage","","","test_search_field",""
|
||||||
|
"failed","Sun Sep 22 21:17:02 MSK 2019","Sun Sep 22 21:17:30 MSK 2019","27582","screenshot_tests.tests","yandex_main_page_test","TestYandexMainPage","","","test_news_widget","Test for news widget."
|
||||||
|
41
allure-report/data/suites.json
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
{
|
||||||
|
"uid" : "98d3104e051c652961429bf95fa0b5d6",
|
||||||
|
"name" : "suites",
|
||||||
|
"children" : [ {
|
||||||
|
"name" : "screenshot_tests.tests",
|
||||||
|
"children" : [ {
|
||||||
|
"name" : "yandex_main_page_test",
|
||||||
|
"children" : [ {
|
||||||
|
"name" : "TestYandexMainPage",
|
||||||
|
"children" : [ {
|
||||||
|
"name" : "test_search_field",
|
||||||
|
"uid" : "ff3cf8e351b44c24",
|
||||||
|
"parentUid" : "14e9fffecf2f365bb44ac41687f56ae6",
|
||||||
|
"status" : "failed",
|
||||||
|
"time" : {
|
||||||
|
"start" : 1569176221591,
|
||||||
|
"stop" : 1569176247587,
|
||||||
|
"duration" : 25996
|
||||||
|
},
|
||||||
|
"flaky" : false,
|
||||||
|
"parameters" : [ ]
|
||||||
|
}, {
|
||||||
|
"name" : "test_news_widget",
|
||||||
|
"uid" : "35bf2eac0f3b5d9d",
|
||||||
|
"parentUid" : "14e9fffecf2f365bb44ac41687f56ae6",
|
||||||
|
"status" : "failed",
|
||||||
|
"time" : {
|
||||||
|
"start" : 1569176222538,
|
||||||
|
"stop" : 1569176250120,
|
||||||
|
"duration" : 27582
|
||||||
|
},
|
||||||
|
"flaky" : false,
|
||||||
|
"parameters" : [ ]
|
||||||
|
} ],
|
||||||
|
"uid" : "14e9fffecf2f365bb44ac41687f56ae6"
|
||||||
|
} ],
|
||||||
|
"uid" : "09b294b6c70fff4ed23fcba65129c6aa"
|
||||||
|
} ],
|
||||||
|
"uid" : "24b6faeef3ea7966bb42e6050a32e636"
|
||||||
|
} ]
|
||||||
|
}
|
||||||
214
allure-report/data/test-cases/35bf2eac0f3b5d9d.json
Normal file
@@ -0,0 +1,214 @@
|
|||||||
|
{
|
||||||
|
"uid" : "35bf2eac0f3b5d9d",
|
||||||
|
"name" : "test_news_widget",
|
||||||
|
"fullName" : "screenshot_tests.tests.yandex_main_page_test.TestYandexMainPage#test_news_widget",
|
||||||
|
"historyId" : "3ef35865270ff1d210fb39b9ab2432e0",
|
||||||
|
"time" : {
|
||||||
|
"start" : 1569176222538,
|
||||||
|
"stop" : 1569176250120,
|
||||||
|
"duration" : 27582
|
||||||
|
},
|
||||||
|
"description" : "Test for news widget.",
|
||||||
|
"descriptionHtml" : "<p>Test for news widget.</p>\n",
|
||||||
|
"status" : "failed",
|
||||||
|
"statusMessage" : "AssertionError: «Хэдер с новостями» отличается на страницах:\nhttps://yandex.ru/\nи\nhttps://yandex.ru/",
|
||||||
|
"statusTrace" : "self = <yandex_main_page_test.TestYandexMainPage object at 0x103a6d2b0>\n\n def test_news_widget(self):\n \"\"\"Test for news widget.\"\"\"\n page = self.get_page(YandexMainPage)\n> self.check_by_screenshot(page.news_header)\n\nscreenshot_tests/tests/yandex_main_page_test.py:12: \n_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ \n\nself = <yandex_main_page_test.TestYandexMainPage object at 0x103a6d2b0>\nelement = <screenshot_tests.page_objects.custom_web_element.CustomWebElement object at 0x103ab4710>\nargs = (), kwargs = {}, diff = 435\nsaved_url = ParseResult(scheme='https', netloc='yandex.ru', path='/', params='', query='', fragment='')\nprod_url = ParseResult(scheme='https', netloc='yandex.ru', path='/', params='', query='', fragment='')\ninfo = '«Хэдер с новостями»'\n\n def check_by_screenshot(self, element: CustomWebElement, *args, **kwargs):\n diff, saved_url, prod_url = self._get_diff(element, *args, **kwargs)\n info = element.description\n> assert diff == 0, f\"{info} отличается на страницах:\\n{saved_url.geturl()}\\nи\\n{prod_url.geturl()}\"\nE AssertionError: «Хэдер с новостями» отличается на страницах:\nE https://yandex.ru/\nE и\nE https://yandex.ru/\n\nscreenshot_tests/utils/screenshots.py:143: AssertionError",
|
||||||
|
"flaky" : false,
|
||||||
|
"beforeStages" : [ {
|
||||||
|
"name" : "_verify_url",
|
||||||
|
"time" : {
|
||||||
|
"start" : 1569176221097,
|
||||||
|
"stop" : 1569176221097,
|
||||||
|
"duration" : 0
|
||||||
|
},
|
||||||
|
"status" : "passed",
|
||||||
|
"steps" : [ ],
|
||||||
|
"attachments" : [ ],
|
||||||
|
"parameters" : [ ],
|
||||||
|
"stepsCount" : 0,
|
||||||
|
"attachmentsCount" : 0,
|
||||||
|
"shouldDisplayMessage" : false,
|
||||||
|
"hasContent" : false
|
||||||
|
}, {
|
||||||
|
"name" : "screenshot_prepare",
|
||||||
|
"time" : {
|
||||||
|
"start" : 1569176221097,
|
||||||
|
"stop" : 1569176221097,
|
||||||
|
"duration" : 0
|
||||||
|
},
|
||||||
|
"status" : "passed",
|
||||||
|
"steps" : [ ],
|
||||||
|
"attachments" : [ ],
|
||||||
|
"parameters" : [ ],
|
||||||
|
"stepsCount" : 0,
|
||||||
|
"attachmentsCount" : 0,
|
||||||
|
"shouldDisplayMessage" : false,
|
||||||
|
"hasContent" : false
|
||||||
|
}, {
|
||||||
|
"name" : "driver",
|
||||||
|
"time" : {
|
||||||
|
"start" : 1569176221097,
|
||||||
|
"stop" : 1569176222535,
|
||||||
|
"duration" : 1438
|
||||||
|
},
|
||||||
|
"status" : "passed",
|
||||||
|
"steps" : [ ],
|
||||||
|
"attachments" : [ ],
|
||||||
|
"parameters" : [ ],
|
||||||
|
"stepsCount" : 0,
|
||||||
|
"attachmentsCount" : 0,
|
||||||
|
"shouldDisplayMessage" : false,
|
||||||
|
"hasContent" : false
|
||||||
|
}, {
|
||||||
|
"name" : "set_driver",
|
||||||
|
"time" : {
|
||||||
|
"start" : 1569176222536,
|
||||||
|
"stop" : 1569176222536,
|
||||||
|
"duration" : 0
|
||||||
|
},
|
||||||
|
"status" : "passed",
|
||||||
|
"steps" : [ ],
|
||||||
|
"attachments" : [ ],
|
||||||
|
"parameters" : [ ],
|
||||||
|
"stepsCount" : 0,
|
||||||
|
"attachmentsCount" : 0,
|
||||||
|
"shouldDisplayMessage" : false,
|
||||||
|
"hasContent" : false
|
||||||
|
}, {
|
||||||
|
"name" : "base_url",
|
||||||
|
"time" : {
|
||||||
|
"start" : 1569176221096,
|
||||||
|
"stop" : 1569176221096,
|
||||||
|
"duration" : 0
|
||||||
|
},
|
||||||
|
"status" : "passed",
|
||||||
|
"steps" : [ ],
|
||||||
|
"attachments" : [ ],
|
||||||
|
"parameters" : [ ],
|
||||||
|
"stepsCount" : 0,
|
||||||
|
"attachmentsCount" : 0,
|
||||||
|
"shouldDisplayMessage" : false,
|
||||||
|
"hasContent" : false
|
||||||
|
}, {
|
||||||
|
"name" : "configure",
|
||||||
|
"time" : {
|
||||||
|
"start" : 1569176221097,
|
||||||
|
"stop" : 1569176221097,
|
||||||
|
"duration" : 0
|
||||||
|
},
|
||||||
|
"status" : "passed",
|
||||||
|
"steps" : [ ],
|
||||||
|
"attachments" : [ ],
|
||||||
|
"parameters" : [ ],
|
||||||
|
"stepsCount" : 0,
|
||||||
|
"attachmentsCount" : 0,
|
||||||
|
"shouldDisplayMessage" : false,
|
||||||
|
"hasContent" : false
|
||||||
|
} ],
|
||||||
|
"testStage" : {
|
||||||
|
"description" : "Test for news widget.",
|
||||||
|
"status" : "failed",
|
||||||
|
"statusMessage" : "AssertionError: «Хэдер с новостями» отличается на страницах:\nhttps://yandex.ru/\nи\nhttps://yandex.ru/",
|
||||||
|
"statusTrace" : "self = <yandex_main_page_test.TestYandexMainPage object at 0x103a6d2b0>\n\n def test_news_widget(self):\n \"\"\"Test for news widget.\"\"\"\n page = self.get_page(YandexMainPage)\n> self.check_by_screenshot(page.news_header)\n\nscreenshot_tests/tests/yandex_main_page_test.py:12: \n_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ \n\nself = <yandex_main_page_test.TestYandexMainPage object at 0x103a6d2b0>\nelement = <screenshot_tests.page_objects.custom_web_element.CustomWebElement object at 0x103ab4710>\nargs = (), kwargs = {}, diff = 435\nsaved_url = ParseResult(scheme='https', netloc='yandex.ru', path='/', params='', query='', fragment='')\nprod_url = ParseResult(scheme='https', netloc='yandex.ru', path='/', params='', query='', fragment='')\ninfo = '«Хэдер с новостями»'\n\n def check_by_screenshot(self, element: CustomWebElement, *args, **kwargs):\n diff, saved_url, prod_url = self._get_diff(element, *args, **kwargs)\n info = element.description\n> assert diff == 0, f\"{info} отличается на страницах:\\n{saved_url.geturl()}\\nи\\n{prod_url.geturl()}\"\nE AssertionError: «Хэдер с новостями» отличается на страницах:\nE https://yandex.ru/\nE и\nE https://yandex.ru/\n\nscreenshot_tests/utils/screenshots.py:143: AssertionError",
|
||||||
|
"steps" : [ ],
|
||||||
|
"attachments" : [ {
|
||||||
|
"uid" : "15b144bb82e16a13",
|
||||||
|
"name" : "diff",
|
||||||
|
"source" : "15b144bb82e16a13.png",
|
||||||
|
"type" : "image/png",
|
||||||
|
"size" : 63598
|
||||||
|
}, {
|
||||||
|
"uid" : "8f9801e50746a9d2",
|
||||||
|
"name" : "actual",
|
||||||
|
"source" : "8f9801e50746a9d2.png",
|
||||||
|
"type" : "image/png",
|
||||||
|
"size" : 63036
|
||||||
|
}, {
|
||||||
|
"uid" : "ae0890108418dd6e",
|
||||||
|
"name" : "expected",
|
||||||
|
"source" : "ae0890108418dd6e.png",
|
||||||
|
"type" : "image/png",
|
||||||
|
"size" : 63550
|
||||||
|
}, {
|
||||||
|
"uid" : "d77bd5a097581fae",
|
||||||
|
"name" : "log",
|
||||||
|
"source" : "d77bd5a097581fae.txt",
|
||||||
|
"type" : "text/plain",
|
||||||
|
"size" : 3118
|
||||||
|
} ],
|
||||||
|
"parameters" : [ ],
|
||||||
|
"stepsCount" : 0,
|
||||||
|
"attachmentsCount" : 4,
|
||||||
|
"shouldDisplayMessage" : true,
|
||||||
|
"hasContent" : true
|
||||||
|
},
|
||||||
|
"afterStages" : [ {
|
||||||
|
"name" : "driver::0",
|
||||||
|
"time" : {
|
||||||
|
"start" : 1569176250196,
|
||||||
|
"stop" : 1569176250287,
|
||||||
|
"duration" : 91
|
||||||
|
},
|
||||||
|
"status" : "passed",
|
||||||
|
"steps" : [ ],
|
||||||
|
"attachments" : [ {
|
||||||
|
"uid" : "7c5f405b92682e2f",
|
||||||
|
"name" : "last url",
|
||||||
|
"source" : "7c5f405b92682e2f.uri",
|
||||||
|
"type" : "text/uri-list",
|
||||||
|
"size" : 18
|
||||||
|
} ],
|
||||||
|
"parameters" : [ ],
|
||||||
|
"stepsCount" : 0,
|
||||||
|
"attachmentsCount" : 1,
|
||||||
|
"shouldDisplayMessage" : false,
|
||||||
|
"hasContent" : true
|
||||||
|
} ],
|
||||||
|
"labels" : [ {
|
||||||
|
"name" : "testType",
|
||||||
|
"value" : "screenshotDiff"
|
||||||
|
}, {
|
||||||
|
"name" : "parentSuite",
|
||||||
|
"value" : "screenshot_tests.tests"
|
||||||
|
}, {
|
||||||
|
"name" : "suite",
|
||||||
|
"value" : "yandex_main_page_test"
|
||||||
|
}, {
|
||||||
|
"name" : "subSuite",
|
||||||
|
"value" : "TestYandexMainPage"
|
||||||
|
}, {
|
||||||
|
"name" : "host",
|
||||||
|
"value" : "macbook-pro"
|
||||||
|
}, {
|
||||||
|
"name" : "thread",
|
||||||
|
"value" : "53352-MainThread"
|
||||||
|
}, {
|
||||||
|
"name" : "framework",
|
||||||
|
"value" : "pytest"
|
||||||
|
}, {
|
||||||
|
"name" : "language",
|
||||||
|
"value" : "cpython3"
|
||||||
|
}, {
|
||||||
|
"name" : "package",
|
||||||
|
"value" : "screenshot_tests.tests.yandex_main_page_test"
|
||||||
|
}, {
|
||||||
|
"name" : "resultFormat",
|
||||||
|
"value" : "allure2"
|
||||||
|
} ],
|
||||||
|
"parameters" : [ ],
|
||||||
|
"links" : [ ],
|
||||||
|
"hidden" : false,
|
||||||
|
"retry" : false,
|
||||||
|
"extra" : {
|
||||||
|
"severity" : "normal",
|
||||||
|
"retries" : [ ],
|
||||||
|
"categories" : [ {
|
||||||
|
"name" : "Product defects",
|
||||||
|
"matchedStatuses" : [ ],
|
||||||
|
"flaky" : false
|
||||||
|
} ],
|
||||||
|
"tags" : [ ]
|
||||||
|
},
|
||||||
|
"source" : "35bf2eac0f3b5d9d.json",
|
||||||
|
"parameterValues" : [ ]
|
||||||
|
}
|
||||||
253
allure-report/data/test-cases/ff3cf8e351b44c24.json
Normal file
@@ -0,0 +1,253 @@
|
|||||||
|
{
|
||||||
|
"uid" : "ff3cf8e351b44c24",
|
||||||
|
"name" : "test_search_field",
|
||||||
|
"fullName" : "screenshot_tests.tests.yandex_main_page_test.TestYandexMainPage#test_search_field",
|
||||||
|
"historyId" : "1c6180a6a50469c5cd152002213dbd36",
|
||||||
|
"time" : {
|
||||||
|
"start" : 1569176221591,
|
||||||
|
"stop" : 1569176247587,
|
||||||
|
"duration" : 25996
|
||||||
|
},
|
||||||
|
"status" : "failed",
|
||||||
|
"statusMessage" : "AssertionError: «Поисковый блок» отличается на страницах:\nhttps://yandex.ru/\nи\nhttps://yandex.ru/",
|
||||||
|
"statusTrace" : "self = <yandex_main_page_test.TestYandexMainPage object at 0x10cb5ccc0>\n\n def test_search_field(self):\n words = [\"foo\", \"bar\", \"lol\", \"kek\", \"cheburek\", \"otus\", \"yandex\", \"google\"]\n page = self.get_page(YandexMainPage)\n \n def action():\n page.search_input.send_keys(random.choice(words))\n \n> self.check_by_screenshot(page.search_field, action)\n\nscreenshot_tests/tests/yandex_main_page_test.py:21: \n_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ \n\nself = <yandex_main_page_test.TestYandexMainPage object at 0x10cb5ccc0>\nelement = <screenshot_tests.page_objects.custom_web_element.CustomWebElement object at 0x10cb875c0>\nargs = (<function TestYandexMainPage.test_search_field.<locals>.action at 0x10cb717b8>,)\nkwargs = {}, diff = 16\nsaved_url = ParseResult(scheme='https', netloc='yandex.ru', path='/', params='', query='', fragment='')\nprod_url = ParseResult(scheme='https', netloc='yandex.ru', path='/', params='', query='', fragment='')\ninfo = '«Поисковый блок»'\n\n def check_by_screenshot(self, element: CustomWebElement, *args, **kwargs):\n diff, saved_url, prod_url = self._get_diff(element, *args, **kwargs)\n info = element.description\n> assert diff == 0, f\"{info} отличается на страницах:\\n{saved_url.geturl()}\\nи\\n{prod_url.geturl()}\"\nE AssertionError: «Поисковый блок» отличается на страницах:\nE https://yandex.ru/\nE и\nE https://yandex.ru/\n\nscreenshot_tests/utils/screenshots.py:143: AssertionError",
|
||||||
|
"flaky" : false,
|
||||||
|
"beforeStages" : [ {
|
||||||
|
"name" : "set_driver",
|
||||||
|
"time" : {
|
||||||
|
"start" : 1569176221588,
|
||||||
|
"stop" : 1569176221588,
|
||||||
|
"duration" : 0
|
||||||
|
},
|
||||||
|
"status" : "passed",
|
||||||
|
"steps" : [ ],
|
||||||
|
"attachments" : [ ],
|
||||||
|
"parameters" : [ ],
|
||||||
|
"stepsCount" : 0,
|
||||||
|
"attachmentsCount" : 0,
|
||||||
|
"shouldDisplayMessage" : false,
|
||||||
|
"hasContent" : false
|
||||||
|
}, {
|
||||||
|
"name" : "base_url",
|
||||||
|
"time" : {
|
||||||
|
"start" : 1569176221097,
|
||||||
|
"stop" : 1569176221097,
|
||||||
|
"duration" : 0
|
||||||
|
},
|
||||||
|
"status" : "passed",
|
||||||
|
"steps" : [ ],
|
||||||
|
"attachments" : [ ],
|
||||||
|
"parameters" : [ ],
|
||||||
|
"stepsCount" : 0,
|
||||||
|
"attachmentsCount" : 0,
|
||||||
|
"shouldDisplayMessage" : false,
|
||||||
|
"hasContent" : false
|
||||||
|
}, {
|
||||||
|
"name" : "configure",
|
||||||
|
"time" : {
|
||||||
|
"start" : 1569176221097,
|
||||||
|
"stop" : 1569176221098,
|
||||||
|
"duration" : 1
|
||||||
|
},
|
||||||
|
"status" : "passed",
|
||||||
|
"steps" : [ ],
|
||||||
|
"attachments" : [ ],
|
||||||
|
"parameters" : [ ],
|
||||||
|
"stepsCount" : 0,
|
||||||
|
"attachmentsCount" : 0,
|
||||||
|
"shouldDisplayMessage" : false,
|
||||||
|
"hasContent" : false
|
||||||
|
}, {
|
||||||
|
"name" : "driver",
|
||||||
|
"time" : {
|
||||||
|
"start" : 1569176221098,
|
||||||
|
"stop" : 1569176221588,
|
||||||
|
"duration" : 490
|
||||||
|
},
|
||||||
|
"status" : "passed",
|
||||||
|
"steps" : [ ],
|
||||||
|
"attachments" : [ ],
|
||||||
|
"parameters" : [ ],
|
||||||
|
"stepsCount" : 0,
|
||||||
|
"attachmentsCount" : 0,
|
||||||
|
"shouldDisplayMessage" : false,
|
||||||
|
"hasContent" : false
|
||||||
|
}, {
|
||||||
|
"name" : "screenshot_prepare",
|
||||||
|
"time" : {
|
||||||
|
"start" : 1569176221098,
|
||||||
|
"stop" : 1569176221098,
|
||||||
|
"duration" : 0
|
||||||
|
},
|
||||||
|
"status" : "passed",
|
||||||
|
"steps" : [ ],
|
||||||
|
"attachments" : [ ],
|
||||||
|
"parameters" : [ ],
|
||||||
|
"stepsCount" : 0,
|
||||||
|
"attachmentsCount" : 0,
|
||||||
|
"shouldDisplayMessage" : false,
|
||||||
|
"hasContent" : false
|
||||||
|
}, {
|
||||||
|
"name" : "_verify_url",
|
||||||
|
"time" : {
|
||||||
|
"start" : 1569176221097,
|
||||||
|
"stop" : 1569176221097,
|
||||||
|
"duration" : 0
|
||||||
|
},
|
||||||
|
"status" : "passed",
|
||||||
|
"steps" : [ ],
|
||||||
|
"attachments" : [ ],
|
||||||
|
"parameters" : [ ],
|
||||||
|
"stepsCount" : 0,
|
||||||
|
"attachmentsCount" : 0,
|
||||||
|
"shouldDisplayMessage" : false,
|
||||||
|
"hasContent" : false
|
||||||
|
} ],
|
||||||
|
"testStage" : {
|
||||||
|
"status" : "failed",
|
||||||
|
"statusMessage" : "AssertionError: «Поисковый блок» отличается на страницах:\nhttps://yandex.ru/\nи\nhttps://yandex.ru/",
|
||||||
|
"statusTrace" : "self = <yandex_main_page_test.TestYandexMainPage object at 0x10cb5ccc0>\n\n def test_search_field(self):\n words = [\"foo\", \"bar\", \"lol\", \"kek\", \"cheburek\", \"otus\", \"yandex\", \"google\"]\n page = self.get_page(YandexMainPage)\n \n def action():\n page.search_input.send_keys(random.choice(words))\n \n> self.check_by_screenshot(page.search_field, action)\n\nscreenshot_tests/tests/yandex_main_page_test.py:21: \n_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ \n\nself = <yandex_main_page_test.TestYandexMainPage object at 0x10cb5ccc0>\nelement = <screenshot_tests.page_objects.custom_web_element.CustomWebElement object at 0x10cb875c0>\nargs = (<function TestYandexMainPage.test_search_field.<locals>.action at 0x10cb717b8>,)\nkwargs = {}, diff = 16\nsaved_url = ParseResult(scheme='https', netloc='yandex.ru', path='/', params='', query='', fragment='')\nprod_url = ParseResult(scheme='https', netloc='yandex.ru', path='/', params='', query='', fragment='')\ninfo = '«Поисковый блок»'\n\n def check_by_screenshot(self, element: CustomWebElement, *args, **kwargs):\n diff, saved_url, prod_url = self._get_diff(element, *args, **kwargs)\n info = element.description\n> assert diff == 0, f\"{info} отличается на страницах:\\n{saved_url.geturl()}\\nи\\n{prod_url.geturl()}\"\nE AssertionError: «Поисковый блок» отличается на страницах:\nE https://yandex.ru/\nE и\nE https://yandex.ru/\n\nscreenshot_tests/utils/screenshots.py:143: AssertionError",
|
||||||
|
"steps" : [ {
|
||||||
|
"name" : "Send text ['lol'] to «Поисковый инпут»",
|
||||||
|
"time" : {
|
||||||
|
"start" : 1569176223631,
|
||||||
|
"stop" : 1569176223862,
|
||||||
|
"duration" : 231
|
||||||
|
},
|
||||||
|
"status" : "passed",
|
||||||
|
"steps" : [ ],
|
||||||
|
"attachments" : [ ],
|
||||||
|
"parameters" : [ {
|
||||||
|
"name" : "locator_type",
|
||||||
|
"value" : "'css selector'"
|
||||||
|
}, {
|
||||||
|
"name" : "locator",
|
||||||
|
"value" : "'.input__control'"
|
||||||
|
} ],
|
||||||
|
"stepsCount" : 0,
|
||||||
|
"attachmentsCount" : 0,
|
||||||
|
"shouldDisplayMessage" : false,
|
||||||
|
"hasContent" : true
|
||||||
|
}, {
|
||||||
|
"name" : "Send text ['cheburek'] to «Поисковый инпут»",
|
||||||
|
"time" : {
|
||||||
|
"start" : 1569176235178,
|
||||||
|
"stop" : 1569176235397,
|
||||||
|
"duration" : 219
|
||||||
|
},
|
||||||
|
"status" : "passed",
|
||||||
|
"steps" : [ ],
|
||||||
|
"attachments" : [ ],
|
||||||
|
"parameters" : [ {
|
||||||
|
"name" : "locator_type",
|
||||||
|
"value" : "'css selector'"
|
||||||
|
}, {
|
||||||
|
"name" : "locator",
|
||||||
|
"value" : "'.input__control'"
|
||||||
|
} ],
|
||||||
|
"stepsCount" : 0,
|
||||||
|
"attachmentsCount" : 0,
|
||||||
|
"shouldDisplayMessage" : false,
|
||||||
|
"hasContent" : true
|
||||||
|
} ],
|
||||||
|
"attachments" : [ {
|
||||||
|
"uid" : "d807dd446712ec34",
|
||||||
|
"name" : "diff",
|
||||||
|
"source" : "d807dd446712ec34.png",
|
||||||
|
"type" : "image/png",
|
||||||
|
"size" : 5806
|
||||||
|
}, {
|
||||||
|
"uid" : "43262d127c532fc2",
|
||||||
|
"name" : "actual",
|
||||||
|
"source" : "43262d127c532fc2.png",
|
||||||
|
"type" : "image/png",
|
||||||
|
"size" : 5602
|
||||||
|
}, {
|
||||||
|
"uid" : "e4728e62a9273013",
|
||||||
|
"name" : "expected",
|
||||||
|
"source" : "e4728e62a9273013.png",
|
||||||
|
"type" : "image/png",
|
||||||
|
"size" : 5814
|
||||||
|
}, {
|
||||||
|
"uid" : "6f4fd4816dedd724",
|
||||||
|
"name" : "log",
|
||||||
|
"source" : "6f4fd4816dedd724.txt",
|
||||||
|
"type" : "text/plain",
|
||||||
|
"size" : 2838
|
||||||
|
} ],
|
||||||
|
"parameters" : [ ],
|
||||||
|
"stepsCount" : 2,
|
||||||
|
"attachmentsCount" : 4,
|
||||||
|
"shouldDisplayMessage" : true,
|
||||||
|
"hasContent" : true
|
||||||
|
},
|
||||||
|
"afterStages" : [ {
|
||||||
|
"name" : "driver::0",
|
||||||
|
"time" : {
|
||||||
|
"start" : 1569176247715,
|
||||||
|
"stop" : 1569176247818,
|
||||||
|
"duration" : 103
|
||||||
|
},
|
||||||
|
"status" : "passed",
|
||||||
|
"steps" : [ ],
|
||||||
|
"attachments" : [ {
|
||||||
|
"uid" : "f764d0c1f0c002e8",
|
||||||
|
"name" : "last url",
|
||||||
|
"source" : "f764d0c1f0c002e8.uri",
|
||||||
|
"type" : "text/uri-list",
|
||||||
|
"size" : 18
|
||||||
|
} ],
|
||||||
|
"parameters" : [ ],
|
||||||
|
"stepsCount" : 0,
|
||||||
|
"attachmentsCount" : 1,
|
||||||
|
"shouldDisplayMessage" : false,
|
||||||
|
"hasContent" : true
|
||||||
|
} ],
|
||||||
|
"labels" : [ {
|
||||||
|
"name" : "testType",
|
||||||
|
"value" : "screenshotDiff"
|
||||||
|
}, {
|
||||||
|
"name" : "parentSuite",
|
||||||
|
"value" : "screenshot_tests.tests"
|
||||||
|
}, {
|
||||||
|
"name" : "suite",
|
||||||
|
"value" : "yandex_main_page_test"
|
||||||
|
}, {
|
||||||
|
"name" : "subSuite",
|
||||||
|
"value" : "TestYandexMainPage"
|
||||||
|
}, {
|
||||||
|
"name" : "host",
|
||||||
|
"value" : "macbook-pro"
|
||||||
|
}, {
|
||||||
|
"name" : "thread",
|
||||||
|
"value" : "53353-MainThread"
|
||||||
|
}, {
|
||||||
|
"name" : "framework",
|
||||||
|
"value" : "pytest"
|
||||||
|
}, {
|
||||||
|
"name" : "language",
|
||||||
|
"value" : "cpython3"
|
||||||
|
}, {
|
||||||
|
"name" : "package",
|
||||||
|
"value" : "screenshot_tests.tests.yandex_main_page_test"
|
||||||
|
}, {
|
||||||
|
"name" : "resultFormat",
|
||||||
|
"value" : "allure2"
|
||||||
|
} ],
|
||||||
|
"parameters" : [ ],
|
||||||
|
"links" : [ ],
|
||||||
|
"hidden" : false,
|
||||||
|
"retry" : false,
|
||||||
|
"extra" : {
|
||||||
|
"severity" : "normal",
|
||||||
|
"retries" : [ ],
|
||||||
|
"categories" : [ {
|
||||||
|
"name" : "Product defects",
|
||||||
|
"matchedStatuses" : [ ],
|
||||||
|
"flaky" : false
|
||||||
|
} ],
|
||||||
|
"tags" : [ ]
|
||||||
|
},
|
||||||
|
"source" : "ff3cf8e351b44c24.json",
|
||||||
|
"parameterValues" : [ ]
|
||||||
|
}
|
||||||
41
allure-report/data/timeline.json
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
{
|
||||||
|
"uid" : "ab17fc5a4eb3bca4b216b548c7f9fcbc",
|
||||||
|
"name" : "timeline",
|
||||||
|
"children" : [ {
|
||||||
|
"name" : "macbook-pro",
|
||||||
|
"children" : [ {
|
||||||
|
"name" : "53353-MainThread",
|
||||||
|
"children" : [ {
|
||||||
|
"name" : "test_search_field",
|
||||||
|
"uid" : "ff3cf8e351b44c24",
|
||||||
|
"parentUid" : "4dc7c33bb080a46cee81e32def5d44d1",
|
||||||
|
"status" : "failed",
|
||||||
|
"time" : {
|
||||||
|
"start" : 1569176221591,
|
||||||
|
"stop" : 1569176247587,
|
||||||
|
"duration" : 25996
|
||||||
|
},
|
||||||
|
"flaky" : false,
|
||||||
|
"parameters" : [ ]
|
||||||
|
} ],
|
||||||
|
"uid" : "4dc7c33bb080a46cee81e32def5d44d1"
|
||||||
|
}, {
|
||||||
|
"name" : "53352-MainThread",
|
||||||
|
"children" : [ {
|
||||||
|
"name" : "test_news_widget",
|
||||||
|
"uid" : "35bf2eac0f3b5d9d",
|
||||||
|
"parentUid" : "49e92ccdd5930a6380d1611838fa2485",
|
||||||
|
"status" : "failed",
|
||||||
|
"time" : {
|
||||||
|
"start" : 1569176222538,
|
||||||
|
"stop" : 1569176250120,
|
||||||
|
"duration" : 27582
|
||||||
|
},
|
||||||
|
"flaky" : false,
|
||||||
|
"parameters" : [ ]
|
||||||
|
} ],
|
||||||
|
"uid" : "49e92ccdd5930a6380d1611838fa2485"
|
||||||
|
} ],
|
||||||
|
"uid" : "45427d043511ae68e4401efdf1d10cf3"
|
||||||
|
} ]
|
||||||
|
}
|
||||||
12
allure-report/export/influxDbData.txt
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
launch_status failed=2 1569176258000000000
|
||||||
|
launch_status broken=0 1569176258000000000
|
||||||
|
launch_status passed=0 1569176258000000000
|
||||||
|
launch_status skipped=0 1569176258000000000
|
||||||
|
launch_status unknown=0 1569176258000000000
|
||||||
|
launch_time duration=28529 1569176258000000000
|
||||||
|
launch_time min_duration=25996 1569176258000000000
|
||||||
|
launch_time max_duration=27582 1569176258000000000
|
||||||
|
launch_time sum_duration=53578 1569176258000000000
|
||||||
|
launch_problems product_defects=2 1569176258000000000
|
||||||
|
launch_retries retries=0 1569176258000000000
|
||||||
|
launch_retries run=2 1569176258000000000
|
||||||
10
allure-report/export/mail.html
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<title>Allure Report summary mail</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
Mail body
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
12
allure-report/export/prometheusData.txt
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
launch_status_failed 2
|
||||||
|
launch_status_broken 0
|
||||||
|
launch_status_passed 0
|
||||||
|
launch_status_skipped 0
|
||||||
|
launch_status_unknown 0
|
||||||
|
launch_time_duration 28529
|
||||||
|
launch_time_min_duration 25996
|
||||||
|
launch_time_max_duration 27582
|
||||||
|
launch_time_sum_duration 53578
|
||||||
|
launch_problems_product_defects 2
|
||||||
|
launch_retries_retries 0
|
||||||
|
launch_retries_run 2
|
||||||
BIN
allure-report/favicon.ico
Normal file
|
After Width: | Height: | Size: 15 KiB |
5
allure-report/history/categories-trend.json
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
[ {
|
||||||
|
"data" : {
|
||||||
|
"Product defects" : 2
|
||||||
|
}
|
||||||
|
} ]
|
||||||
5
allure-report/history/duration-trend.json
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
[ {
|
||||||
|
"data" : {
|
||||||
|
"duration" : 28529
|
||||||
|
}
|
||||||
|
} ]
|
||||||
10
allure-report/history/history-trend.json
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
[ {
|
||||||
|
"data" : {
|
||||||
|
"failed" : 2,
|
||||||
|
"broken" : 0,
|
||||||
|
"skipped" : 0,
|
||||||
|
"passed" : 0,
|
||||||
|
"unknown" : 0,
|
||||||
|
"total" : 2
|
||||||
|
}
|
||||||
|
} ]
|
||||||
42
allure-report/history/history.json
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
{
|
||||||
|
"3ef35865270ff1d210fb39b9ab2432e0" : {
|
||||||
|
"statistic" : {
|
||||||
|
"failed" : 1,
|
||||||
|
"broken" : 0,
|
||||||
|
"skipped" : 0,
|
||||||
|
"passed" : 0,
|
||||||
|
"unknown" : 0,
|
||||||
|
"total" : 1
|
||||||
|
},
|
||||||
|
"items" : [ {
|
||||||
|
"uid" : "35bf2eac0f3b5d9d",
|
||||||
|
"status" : "failed",
|
||||||
|
"statusDetails" : "AssertionError: «Хэдер с новостями» отличается на страницах:\nhttps://yandex.ru/\nи\nhttps://yandex.ru/",
|
||||||
|
"time" : {
|
||||||
|
"start" : 1569176222538,
|
||||||
|
"stop" : 1569176250120,
|
||||||
|
"duration" : 27582
|
||||||
|
}
|
||||||
|
} ]
|
||||||
|
},
|
||||||
|
"1c6180a6a50469c5cd152002213dbd36" : {
|
||||||
|
"statistic" : {
|
||||||
|
"failed" : 1,
|
||||||
|
"broken" : 0,
|
||||||
|
"skipped" : 0,
|
||||||
|
"passed" : 0,
|
||||||
|
"unknown" : 0,
|
||||||
|
"total" : 1
|
||||||
|
},
|
||||||
|
"items" : [ {
|
||||||
|
"uid" : "ff3cf8e351b44c24",
|
||||||
|
"status" : "failed",
|
||||||
|
"statusDetails" : "AssertionError: «Поисковый блок» отличается на страницах:\nhttps://yandex.ru/\nи\nhttps://yandex.ru/",
|
||||||
|
"time" : {
|
||||||
|
"start" : 1569176221591,
|
||||||
|
"stop" : 1569176247587,
|
||||||
|
"duration" : 25996
|
||||||
|
}
|
||||||
|
} ]
|
||||||
|
}
|
||||||
|
}
|
||||||
6
allure-report/history/retry-trend.json
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
[ {
|
||||||
|
"data" : {
|
||||||
|
"run" : 2,
|
||||||
|
"retry" : 0
|
||||||
|
}
|
||||||
|
} ]
|
||||||
23
allure-report/index.html
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html dir="ltr">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<title>Allure Report</title>
|
||||||
|
<link rel="favicon" href="favicon.ico?v=2">
|
||||||
|
<link rel="stylesheet" href="styles.css">
|
||||||
|
<link rel="stylesheet" href="plugins/screen-diff/styles.css">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="alert"></div>
|
||||||
|
<div id="content">
|
||||||
|
<span class="spinner">
|
||||||
|
<span class="spinner__circle"></span>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div id="popup"></div>
|
||||||
|
<script src="app.js"></script>
|
||||||
|
<script src="plugins/behaviors/index.js"></script>
|
||||||
|
<script src="plugins/packages/index.js"></script>
|
||||||
|
<script src="plugins/screen-diff/index.js"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
108
allure-report/plugins/behaviors/index.js
Normal file
@@ -0,0 +1,108 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
allure.api.addTranslation('en', {
|
||||||
|
tab: {
|
||||||
|
behaviors: {
|
||||||
|
name: 'Behaviors'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
widget: {
|
||||||
|
behaviors: {
|
||||||
|
name: 'Features by stories',
|
||||||
|
showAll: 'show all'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
allure.api.addTranslation('ru', {
|
||||||
|
tab: {
|
||||||
|
behaviors: {
|
||||||
|
name: 'Функциональность'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
widget: {
|
||||||
|
behaviors: {
|
||||||
|
name: 'Функциональность',
|
||||||
|
showAll: 'показать все'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
allure.api.addTranslation('zh', {
|
||||||
|
tab: {
|
||||||
|
behaviors: {
|
||||||
|
name: '功能'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
widget: {
|
||||||
|
behaviors: {
|
||||||
|
name: '特性场景',
|
||||||
|
showAll: '显示所有'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
allure.api.addTranslation('de', {
|
||||||
|
tab: {
|
||||||
|
behaviors: {
|
||||||
|
name: 'Verhalten'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
widget: {
|
||||||
|
behaviors: {
|
||||||
|
name: 'Features nach Stories',
|
||||||
|
showAll: 'Zeige alle'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
allure.api.addTranslation('he', {
|
||||||
|
tab: {
|
||||||
|
behaviors: {
|
||||||
|
name: 'התנהגויות'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
widget: {
|
||||||
|
behaviors: {
|
||||||
|
name: 'תכונות לפי סיפורי משתמש',
|
||||||
|
showAll: 'הצג הכול'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
allure.api.addTranslation('br', {
|
||||||
|
tab: {
|
||||||
|
behaviors: {
|
||||||
|
name: 'Comportamentos'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
widget: {
|
||||||
|
behaviors: {
|
||||||
|
name: 'Funcionalidades por história',
|
||||||
|
showAll: 'Mostrar tudo'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
allure.api.addTab('behaviors', {
|
||||||
|
title: 'tab.behaviors.name', icon: 'fa fa-list',
|
||||||
|
route: 'behaviors(/)(:testGroup)(/)(:testResult)(/)(:testResultTab)(/)',
|
||||||
|
onEnter: (function (testGroup, testResult, testResultTab) {
|
||||||
|
return new allure.components.TreeLayout({
|
||||||
|
testGroup: testGroup,
|
||||||
|
testResult: testResult,
|
||||||
|
testResultTab: testResultTab,
|
||||||
|
tabName: 'tab.behaviors.name',
|
||||||
|
baseUrl: 'behaviors',
|
||||||
|
url: 'data/behaviors.json',
|
||||||
|
csvUrl: 'data/behaviors.csv'
|
||||||
|
});
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
allure.api.addWidget('widgets', 'behaviors', allure.components.WidgetStatusView.extend({
|
||||||
|
rowTag: 'a',
|
||||||
|
title: 'widget.behaviors.name',
|
||||||
|
baseUrl: 'behaviors',
|
||||||
|
showLinks: true
|
||||||
|
}));
|
||||||
64
allure-report/plugins/packages/index.js
Normal file
@@ -0,0 +1,64 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
allure.api.addTranslation('en', {
|
||||||
|
tab: {
|
||||||
|
packages: {
|
||||||
|
name: 'Packages'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
allure.api.addTranslation('ru', {
|
||||||
|
tab: {
|
||||||
|
packages: {
|
||||||
|
name: 'Пакеты'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
allure.api.addTranslation('zh', {
|
||||||
|
tab: {
|
||||||
|
packages: {
|
||||||
|
name: '包'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
allure.api.addTranslation('de', {
|
||||||
|
tab: {
|
||||||
|
packages: {
|
||||||
|
name: 'Pakete'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
allure.api.addTranslation('he', {
|
||||||
|
tab: {
|
||||||
|
packages: {
|
||||||
|
name: 'חבילות'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
allure.api.addTranslation('br', {
|
||||||
|
tab: {
|
||||||
|
packages: {
|
||||||
|
name: 'Pacotes'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
allure.api.addTab('packages', {
|
||||||
|
title: 'tab.packages.name', icon: 'fa fa-align-left',
|
||||||
|
route: 'packages(/)(:testGroup)(/)(:testResult)(/)(:testResultTab)(/)',
|
||||||
|
onEnter: (function (testGroup, testResult, testResultTab) {
|
||||||
|
return new allure.components.TreeLayout({
|
||||||
|
testGroup: testGroup,
|
||||||
|
testResult: testResult,
|
||||||
|
testResultTab: testResultTab,
|
||||||
|
tabName: 'tab.packages.name',
|
||||||
|
baseUrl: 'packages',
|
||||||
|
url: 'data/packages.json'
|
||||||
|
});
|
||||||
|
})
|
||||||
|
});
|
||||||
97
allure-report/plugins/screen-diff/index.js
Normal file
@@ -0,0 +1,97 @@
|
|||||||
|
(function () {
|
||||||
|
var settings = allure.getPluginSettings('screen-diff', {diffType: 'diff'});
|
||||||
|
|
||||||
|
function renderImage(src) {
|
||||||
|
return '<div class="screen-diff__container">' +
|
||||||
|
'<img class="screen-diff__image" src="data/attachments/' + src + '">' +
|
||||||
|
'</div>';
|
||||||
|
}
|
||||||
|
|
||||||
|
function renderDiffContent(type, data) {
|
||||||
|
function findImage(name) {
|
||||||
|
if (data.testStage && data.testStage.attachments) {
|
||||||
|
return data.testStage.attachments.filter(function (attachment) {
|
||||||
|
return attachment.name === name;
|
||||||
|
})[0];
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
var diffImage = findImage('diff');
|
||||||
|
var actualImage = findImage('actual');
|
||||||
|
var expectedImage = findImage('expected');
|
||||||
|
|
||||||
|
if (!diffImage && !actualImage && !expectedImage) {
|
||||||
|
return '<span>Diff, actual and expected image have not been provided.</span>';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (type === 'diff') {
|
||||||
|
if (!diffImage) {
|
||||||
|
return renderImage(actualImage.source);
|
||||||
|
}
|
||||||
|
return renderImage(diffImage.source);
|
||||||
|
}
|
||||||
|
if (type === 'overlay') {
|
||||||
|
return '<div class="screen-diff__overlay screen-diff__container">' +
|
||||||
|
'<img class="screen-diff__image" src="data/attachments/' + expectedImage.source + '">' +
|
||||||
|
'<div class="screen-diff__image-over">' +
|
||||||
|
'<img class="screen-diff__image" src="data/attachments/' + actualImage.source + '">' +
|
||||||
|
'</div>' +
|
||||||
|
'</div>';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var ScreenDiffView = Backbone.Marionette.View.extend({
|
||||||
|
className: 'pane__section',
|
||||||
|
events: {
|
||||||
|
'click [name="screen-diff-type"]': 'onDiffTypeChange',
|
||||||
|
'mousemove .screen-diff__overlay': 'onOverlayMove'
|
||||||
|
},
|
||||||
|
templateContext: function () {
|
||||||
|
return {
|
||||||
|
diffType: settings.get('diffType')
|
||||||
|
}
|
||||||
|
},
|
||||||
|
template: function (data) {
|
||||||
|
var testType = data.labels.filter(function (label) {
|
||||||
|
return label.name === 'testType'
|
||||||
|
})[0];
|
||||||
|
|
||||||
|
if (!testType || testType.value !== 'screenshotDiff') {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
return '<h3 class="pane__section-title">Screen Diff</h3>' +
|
||||||
|
'<div class="screen-diff__content">' +
|
||||||
|
'<div class="screen-diff__switchers">' +
|
||||||
|
'<label><input type="radio" name="screen-diff-type" value="diff"> Show diff</label>' +
|
||||||
|
'<label><input type="radio" name="screen-diff-type" value="overlay"> Show overlay</label>' +
|
||||||
|
'</div>' +
|
||||||
|
renderDiffContent(data.diffType, data) +
|
||||||
|
'</div>';
|
||||||
|
},
|
||||||
|
adjustImageSize: function (event) {
|
||||||
|
var overImage = this.$(event.target);
|
||||||
|
overImage.width(overImage.width());
|
||||||
|
},
|
||||||
|
onRender: function () {
|
||||||
|
const diffType = settings.get('diffType');
|
||||||
|
this.$('[name="screen-diff-type"][value="' + diffType + '"]').prop('checked', true);
|
||||||
|
if (diffType === 'overlay') {
|
||||||
|
this.$('.screen-diff__image-over img').on('load', this.adjustImageSize.bind(this));
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onOverlayMove: function (event) {
|
||||||
|
var pageX = event.pageX;
|
||||||
|
var containerScroll = this.$('.screen-diff__container').scrollLeft();
|
||||||
|
var elementX = event.currentTarget.getBoundingClientRect().left;
|
||||||
|
var delta = pageX - elementX + containerScroll;
|
||||||
|
this.$('.screen-diff__image-over').width(delta);
|
||||||
|
},
|
||||||
|
onDiffTypeChange: function (event) {
|
||||||
|
settings.save('diffType', event.target.value);
|
||||||
|
this.render();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
allure.api.addTestResultBlock(ScreenDiffView, {position: 'before'});
|
||||||
|
})();
|
||||||
26
allure-report/plugins/screen-diff/styles.css
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
.screen-diff__switchers {
|
||||||
|
margin-bottom: 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.screen-diff__switchers label + label {
|
||||||
|
margin-left: 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.screen-diff__overlay {
|
||||||
|
position: relative;
|
||||||
|
cursor: col-resize;
|
||||||
|
}
|
||||||
|
|
||||||
|
.screen-diff__container {
|
||||||
|
overflow-x: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.screen-diff__image-over {
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
bottom: 0;
|
||||||
|
background: #fff;
|
||||||
|
position: absolute;
|
||||||
|
overflow: hidden;
|
||||||
|
box-shadow: 2px 0 1px -1px #aaa;
|
||||||
|
}
|
||||||
4
allure-report/styles.css
Normal file
4
allure-report/widgets/behaviors.json
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
{
|
||||||
|
"total" : 2,
|
||||||
|
"items" : [ ]
|
||||||
|
}
|
||||||
5
allure-report/widgets/categories-trend.json
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
[ {
|
||||||
|
"data" : {
|
||||||
|
"Product defects" : 2
|
||||||
|
}
|
||||||
|
} ]
|
||||||
15
allure-report/widgets/categories.json
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
{
|
||||||
|
"total" : 1,
|
||||||
|
"items" : [ {
|
||||||
|
"uid" : "8fb3a91ba5aaf9de24cc8a92edc82b5d",
|
||||||
|
"name" : "Product defects",
|
||||||
|
"statistic" : {
|
||||||
|
"failed" : 2,
|
||||||
|
"broken" : 0,
|
||||||
|
"skipped" : 0,
|
||||||
|
"passed" : 0,
|
||||||
|
"unknown" : 0,
|
||||||
|
"total" : 2
|
||||||
|
}
|
||||||
|
} ]
|
||||||
|
}
|
||||||
5
allure-report/widgets/duration-trend.json
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
[ {
|
||||||
|
"data" : {
|
||||||
|
"duration" : 28529
|
||||||
|
}
|
||||||
|
} ]
|
||||||
21
allure-report/widgets/duration.json
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
[ {
|
||||||
|
"uid" : "ff3cf8e351b44c24",
|
||||||
|
"name" : "test_search_field",
|
||||||
|
"time" : {
|
||||||
|
"start" : 1569176221591,
|
||||||
|
"stop" : 1569176247587,
|
||||||
|
"duration" : 25996
|
||||||
|
},
|
||||||
|
"status" : "failed",
|
||||||
|
"severity" : "normal"
|
||||||
|
}, {
|
||||||
|
"uid" : "35bf2eac0f3b5d9d",
|
||||||
|
"name" : "test_news_widget",
|
||||||
|
"time" : {
|
||||||
|
"start" : 1569176222538,
|
||||||
|
"stop" : 1569176250120,
|
||||||
|
"duration" : 27582
|
||||||
|
},
|
||||||
|
"status" : "failed",
|
||||||
|
"severity" : "normal"
|
||||||
|
} ]
|
||||||
1
allure-report/widgets/environment.json
Normal file
@@ -0,0 +1 @@
|
|||||||
|
[ ]
|
||||||
1
allure-report/widgets/executors.json
Normal file
@@ -0,0 +1 @@
|
|||||||
|
[ ]
|
||||||
10
allure-report/widgets/history-trend.json
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
[ {
|
||||||
|
"data" : {
|
||||||
|
"failed" : 2,
|
||||||
|
"broken" : 0,
|
||||||
|
"skipped" : 0,
|
||||||
|
"passed" : 0,
|
||||||
|
"unknown" : 0,
|
||||||
|
"total" : 2
|
||||||
|
}
|
||||||
|
} ]
|
||||||
1
allure-report/widgets/launch.json
Normal file
@@ -0,0 +1 @@
|
|||||||
|
[ ]
|
||||||
6
allure-report/widgets/retry-trend.json
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
[ {
|
||||||
|
"data" : {
|
||||||
|
"run" : 2,
|
||||||
|
"retry" : 0
|
||||||
|
}
|
||||||
|
} ]
|
||||||
21
allure-report/widgets/severity.json
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
[ {
|
||||||
|
"uid" : "35bf2eac0f3b5d9d",
|
||||||
|
"name" : "test_news_widget",
|
||||||
|
"time" : {
|
||||||
|
"start" : 1569176222538,
|
||||||
|
"stop" : 1569176250120,
|
||||||
|
"duration" : 27582
|
||||||
|
},
|
||||||
|
"status" : "failed",
|
||||||
|
"severity" : "normal"
|
||||||
|
}, {
|
||||||
|
"uid" : "ff3cf8e351b44c24",
|
||||||
|
"name" : "test_search_field",
|
||||||
|
"time" : {
|
||||||
|
"start" : 1569176221591,
|
||||||
|
"stop" : 1569176247587,
|
||||||
|
"duration" : 25996
|
||||||
|
},
|
||||||
|
"status" : "failed",
|
||||||
|
"severity" : "normal"
|
||||||
|
} ]
|
||||||
21
allure-report/widgets/status-chart.json
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
[ {
|
||||||
|
"uid" : "ff3cf8e351b44c24",
|
||||||
|
"name" : "test_search_field",
|
||||||
|
"time" : {
|
||||||
|
"start" : 1569176221591,
|
||||||
|
"stop" : 1569176247587,
|
||||||
|
"duration" : 25996
|
||||||
|
},
|
||||||
|
"status" : "failed",
|
||||||
|
"severity" : "normal"
|
||||||
|
}, {
|
||||||
|
"uid" : "35bf2eac0f3b5d9d",
|
||||||
|
"name" : "test_news_widget",
|
||||||
|
"time" : {
|
||||||
|
"start" : 1569176222538,
|
||||||
|
"stop" : 1569176250120,
|
||||||
|
"duration" : 27582
|
||||||
|
},
|
||||||
|
"status" : "failed",
|
||||||
|
"severity" : "normal"
|
||||||
|
} ]
|
||||||
15
allure-report/widgets/suites.json
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
{
|
||||||
|
"total" : 1,
|
||||||
|
"items" : [ {
|
||||||
|
"uid" : "24b6faeef3ea7966bb42e6050a32e636",
|
||||||
|
"name" : "screenshot_tests.tests",
|
||||||
|
"statistic" : {
|
||||||
|
"failed" : 2,
|
||||||
|
"broken" : 0,
|
||||||
|
"skipped" : 0,
|
||||||
|
"passed" : 0,
|
||||||
|
"unknown" : 0,
|
||||||
|
"total" : 2
|
||||||
|
}
|
||||||
|
} ]
|
||||||
|
}
|
||||||
20
allure-report/widgets/summary.json
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
{
|
||||||
|
"reportName" : "Allure Report",
|
||||||
|
"testRuns" : [ ],
|
||||||
|
"statistic" : {
|
||||||
|
"failed" : 2,
|
||||||
|
"broken" : 0,
|
||||||
|
"skipped" : 0,
|
||||||
|
"passed" : 0,
|
||||||
|
"unknown" : 0,
|
||||||
|
"total" : 2
|
||||||
|
},
|
||||||
|
"time" : {
|
||||||
|
"start" : 1569176221591,
|
||||||
|
"stop" : 1569176250120,
|
||||||
|
"duration" : 28529,
|
||||||
|
"minDuration" : 25996,
|
||||||
|
"maxDuration" : 27582,
|
||||||
|
"sumDuration" : 53578
|
||||||
|
}
|
||||||
|
}
|
||||||
49
conftest.py
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
import pytest
|
||||||
|
import logging
|
||||||
|
import allure
|
||||||
|
from selenium.webdriver import Chrome, ChromeOptions
|
||||||
|
|
||||||
|
|
||||||
|
class Config:
|
||||||
|
BASE_URL = "baseurl"
|
||||||
|
STAGING = "staging"
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture()
|
||||||
|
def driver():
|
||||||
|
options = ChromeOptions()
|
||||||
|
options.add_argument("--headless")
|
||||||
|
webdriver = Chrome(desired_capabilities=options.to_capabilities())
|
||||||
|
webdriver.implicitly_wait(5)
|
||||||
|
yield webdriver
|
||||||
|
allure.attach(webdriver.current_url, "last url", allure.attachment_type.URI_LIST)
|
||||||
|
webdriver.quit()
|
||||||
|
|
||||||
|
|
||||||
|
def pytest_addoption(parser):
|
||||||
|
"""Command line parser."""
|
||||||
|
parser.addoption(f'--{Config.BASE_URL}',
|
||||||
|
default='https://yandex.ru',
|
||||||
|
dest=Config.BASE_URL,
|
||||||
|
action='store',
|
||||||
|
metavar='str',
|
||||||
|
help='Environment for run tests.')
|
||||||
|
parser.addoption(f'--{Config.STAGING}',
|
||||||
|
default='https://yandex.ru',
|
||||||
|
dest=Config.STAGING,
|
||||||
|
action='store',
|
||||||
|
metavar='str',
|
||||||
|
help='Environment for compare with testing.')
|
||||||
|
parser.addoption('--log_level',
|
||||||
|
default='INFO',
|
||||||
|
dest='log_level',
|
||||||
|
action='store',
|
||||||
|
metavar='str',
|
||||||
|
help='Logging level.')
|
||||||
|
|
||||||
|
|
||||||
|
def pytest_configure(config):
|
||||||
|
"""Configure test run."""
|
||||||
|
logging.basicConfig(level=config.getoption('log_level'),
|
||||||
|
format='%(asctime)s [%(levelname)8s] %(message)s (%(filename)s:%(lineno)s)',
|
||||||
|
datefmt='%Y-%m-%d %H:%M:%S')
|
||||||
9
readme.md
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
### Example of screenshot testing in python
|
||||||
|
|
||||||
|
How to:
|
||||||
|
1) Install python 3.6+
|
||||||
|
2) Install deps `pip install requirements.txt`
|
||||||
|
3) Run tests pytest screenshot_tests/tests --alluredir=report
|
||||||
|
4) Generate and open report with Allure CLI [link](https://docs.qameta.io/allure/#_commandline)
|
||||||
|
|
||||||
|
or just open report from repo: `allure open allure-report`
|
||||||
5
requirements.txt
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
pytest==5.1.2
|
||||||
|
flaky==3.6.1
|
||||||
|
selenium==3.141.0
|
||||||
|
allure-pytest==2.8.2
|
||||||
|
Pillow==6.1.0
|
||||||
112
screenshot_tests/image_proccessing/image_processor.py
Normal file
@@ -0,0 +1,112 @@
|
|||||||
|
from PIL import ImageDraw, Image
|
||||||
|
from io import BytesIO
|
||||||
|
from typing import Tuple, List
|
||||||
|
|
||||||
|
import logging
|
||||||
|
|
||||||
|
|
||||||
|
class ImageProcessor(object):
|
||||||
|
"""Class for image comparison."""
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
self._block_width = 20 # default
|
||||||
|
self._block_height = 20
|
||||||
|
self._accuracy = 0.0001 # less better
|
||||||
|
|
||||||
|
def _slice_image(self, image: Image.Image) -> List[dict]:
|
||||||
|
"""Slice image on small blocks."""
|
||||||
|
max_width, max_height = image.size
|
||||||
|
|
||||||
|
width_change = self._block_width
|
||||||
|
height_change = self._block_height
|
||||||
|
|
||||||
|
result = []
|
||||||
|
for row in range(0, max_height, self._block_height):
|
||||||
|
for col in range(0, max_width, self._block_width):
|
||||||
|
# Если дошли до края изображения
|
||||||
|
if width_change > max_width:
|
||||||
|
width_change = max_width
|
||||||
|
# отрезаем по краю
|
||||||
|
if height_change > max_height:
|
||||||
|
height_change = max_height
|
||||||
|
|
||||||
|
# col, row -- верхний левый угол
|
||||||
|
box = (col, row, width_change, height_change)
|
||||||
|
cropped = image.crop(box)
|
||||||
|
result.append({"image": cropped, "box": box})
|
||||||
|
# сдвигаем вправо по ширине
|
||||||
|
width_change += self._block_width
|
||||||
|
|
||||||
|
# сдвигаем вниз по высоте
|
||||||
|
height_change += self._block_height
|
||||||
|
# возвращаем указатель на ширину в стартовую позицию
|
||||||
|
width_change = self._block_width
|
||||||
|
|
||||||
|
return result
|
||||||
|
|
||||||
|
def _get_image_pixel_sum(self, image: Image.Image) -> int:
|
||||||
|
"""Get pixel sum for image."""
|
||||||
|
image_total = 0
|
||||||
|
max_width, max_height = image.size
|
||||||
|
|
||||||
|
for coord_y in range(0, max_height):
|
||||||
|
for coord_x in range(0, max_width):
|
||||||
|
pixel = image.getpixel((coord_x, coord_y))
|
||||||
|
image_total += sum(pixel)
|
||||||
|
|
||||||
|
return image_total
|
||||||
|
|
||||||
|
def get_images_diff(self, first_image: Image.Image, second_image: Image.Image) -> Tuple[int, bytes, bytes, bytes]:
|
||||||
|
"""Compare two images."""
|
||||||
|
result_image = first_image.copy()
|
||||||
|
|
||||||
|
first_image_blocks = self._slice_image(first_image)
|
||||||
|
second_image_blocks = self._slice_image(second_image)
|
||||||
|
|
||||||
|
# если скриншоты разных размеров, то все блоки из большего скриншота, которые не попали в меньший нужно добавить
|
||||||
|
# к битым
|
||||||
|
mistaken_blocks = abs(len(first_image_blocks) - len(second_image_blocks))
|
||||||
|
|
||||||
|
for index in range(min(len(first_image_blocks), len(second_image_blocks))):
|
||||||
|
first_pixels = self._get_image_pixel_sum(first_image_blocks[index]["image"])
|
||||||
|
second_pixels = self._get_image_pixel_sum(second_image_blocks[index]["image"])
|
||||||
|
|
||||||
|
# если пиксели отличаются больше чем на self.accuracy -- помечаем блок как битый
|
||||||
|
if (first_pixels != 0 and second_pixels != 0) and abs(1 - (first_pixels / second_pixels)) >= self._accuracy:
|
||||||
|
draw = ImageDraw.Draw(result_image)
|
||||||
|
draw.rectangle(first_image_blocks[index]["box"], outline="red")
|
||||||
|
mistaken_blocks += 1
|
||||||
|
|
||||||
|
result = BytesIO()
|
||||||
|
first = BytesIO()
|
||||||
|
second = BytesIO()
|
||||||
|
|
||||||
|
result_image.save(result, 'PNG')
|
||||||
|
first_image.save(first, 'PNG')
|
||||||
|
second_image.save(second, 'PNG')
|
||||||
|
|
||||||
|
return mistaken_blocks, result.getvalue(), first.getvalue(), second.getvalue()
|
||||||
|
|
||||||
|
def paste(self, screenshots: List[bytes]) -> Image.Image:
|
||||||
|
"""Concatenate few images into one."""
|
||||||
|
max_width = 0
|
||||||
|
max_height = 0
|
||||||
|
images = []
|
||||||
|
for screenshot in screenshots:
|
||||||
|
image = self.load_image_from_bytes(screenshot)
|
||||||
|
images.append(image)
|
||||||
|
max_width = image.size[0] if image.size[0] > max_width else max_width
|
||||||
|
max_height += image.size[1]
|
||||||
|
result = Image.new('RGB', (max_width, max_height))
|
||||||
|
logging.info(f'Screen size: ({max_width}, {max_height})')
|
||||||
|
offset = 0
|
||||||
|
for image in images:
|
||||||
|
result.paste(image, (0, offset))
|
||||||
|
logging.info(f"Image added, offset is {offset}")
|
||||||
|
offset += image.size[1]
|
||||||
|
|
||||||
|
return result
|
||||||
|
|
||||||
|
def load_image_from_bytes(self, data: bytes):
|
||||||
|
"""Загрузить изображение из байтовой строки."""
|
||||||
|
return Image.open(BytesIO(data))
|
||||||
46
screenshot_tests/page_objects/custom_web_element.py
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
import allure
|
||||||
|
from selenium.webdriver.remote.webelement import WebElement
|
||||||
|
|
||||||
|
|
||||||
|
class CustomWebElement:
|
||||||
|
"""Custom web element with allure logging."""
|
||||||
|
|
||||||
|
def __init__(self, by: str, locator: str, element: WebElement, description: str = None):
|
||||||
|
self.by = by
|
||||||
|
self.locator = locator
|
||||||
|
self.element = element
|
||||||
|
self.description = f"«{description}»" if description else "element"
|
||||||
|
|
||||||
|
def _execute_action(self, action, step):
|
||||||
|
"""Execute action with allure logging.
|
||||||
|
|
||||||
|
:param action: Function to execute. Click, send_keys, etc
|
||||||
|
:param step: Step description.
|
||||||
|
"""
|
||||||
|
@allure.step(step)
|
||||||
|
def execute_action(locator_type=self.by, locator=self.locator):
|
||||||
|
"""All arguments will be available in report."""
|
||||||
|
return action()
|
||||||
|
|
||||||
|
return execute_action()
|
||||||
|
|
||||||
|
def click(self):
|
||||||
|
self._execute_action(self.element.click,
|
||||||
|
f"Click at {self.description}")
|
||||||
|
|
||||||
|
def send_keys(self, *value):
|
||||||
|
self._execute_action(lambda: self.element.send_keys(*value),
|
||||||
|
f"Send text {[v for v in value]} to {self.description}")
|
||||||
|
|
||||||
|
def __eq__(self, element):
|
||||||
|
return self.element.__eq__(element)
|
||||||
|
|
||||||
|
def __ne__(self, element):
|
||||||
|
return self.element.__ne__(element)
|
||||||
|
|
||||||
|
def __hash__(self):
|
||||||
|
return self.element.__hash__()
|
||||||
|
|
||||||
|
def __getattr__(self, item):
|
||||||
|
"""Missing methods will be executed from WebElement."""
|
||||||
|
return getattr(self.element, item)
|
||||||
42
screenshot_tests/page_objects/elements.py
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
from selenium.webdriver import Remote
|
||||||
|
from selenium.webdriver.common import by as selenium_by
|
||||||
|
from screenshot_tests.page_objects.custom_web_element import CustomWebElement
|
||||||
|
from typing import Union, TypeVar, Type
|
||||||
|
|
||||||
|
Locators = selenium_by.By
|
||||||
|
|
||||||
|
|
||||||
|
class Page:
|
||||||
|
"""Base page for all pages in PO."""
|
||||||
|
|
||||||
|
path = None
|
||||||
|
|
||||||
|
def __init__(self, driver: Remote):
|
||||||
|
self.driver = driver
|
||||||
|
|
||||||
|
|
||||||
|
PageBoundGeneric = TypeVar("PageBoundGeneric", bound=Page)
|
||||||
|
|
||||||
|
|
||||||
|
class Element:
|
||||||
|
"""Element descriptor for WebElement lazy init."""
|
||||||
|
|
||||||
|
def __init__(self, by: str, locator: str, description: str):
|
||||||
|
self.by = by
|
||||||
|
self.locator = locator
|
||||||
|
self.description = description
|
||||||
|
|
||||||
|
def __get__(self,
|
||||||
|
instance: PageBoundGeneric,
|
||||||
|
owner: Type[PageBoundGeneric]) -> Union[CustomWebElement, 'Element']:
|
||||||
|
"""
|
||||||
|
https://docs.python.org/3/howto/descriptor.html
|
||||||
|
:param instance: instance of owner
|
||||||
|
:param owner: type of owner
|
||||||
|
:return: self or WebElement instance
|
||||||
|
"""
|
||||||
|
if isinstance(instance, Element):
|
||||||
|
return self
|
||||||
|
|
||||||
|
return CustomWebElement(self.by, self.locator, instance.driver.find_element(self.by, self.locator),
|
||||||
|
self.description)
|
||||||
11
screenshot_tests/page_objects/pages/yandex_main_page.py
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
from screenshot_tests.page_objects.elements import Page, Element, Locators
|
||||||
|
|
||||||
|
|
||||||
|
class YandexMainPage(Page):
|
||||||
|
"""https://yandex.ru"""
|
||||||
|
|
||||||
|
path = ""
|
||||||
|
|
||||||
|
news_header = Element(Locators.CSS_SELECTOR, ".news__header", "Хэдер с новостями")
|
||||||
|
search_field = Element(Locators.CSS_SELECTOR, ".search2", "Поисковый блок")
|
||||||
|
search_input = Element(Locators.CSS_SELECTOR, ".input__control", "Поисковый инпут")
|
||||||
21
screenshot_tests/tests/yandex_main_page_test.py
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
from screenshot_tests.utils.screenshots import TestCase
|
||||||
|
from screenshot_tests.page_objects.pages.yandex_main_page import YandexMainPage
|
||||||
|
import random
|
||||||
|
|
||||||
|
|
||||||
|
class TestYandexMainPage(TestCase):
|
||||||
|
"""Tests for https://yandex.ru"""
|
||||||
|
|
||||||
|
def test_news_widget(self):
|
||||||
|
"""Test for news widget."""
|
||||||
|
page = self.get_page(YandexMainPage)
|
||||||
|
self.check_by_screenshot(page.news_header)
|
||||||
|
|
||||||
|
def test_search_field(self):
|
||||||
|
words = ["foo", "bar", "lol", "kek", "cheburek", "otus", "yandex", "google"]
|
||||||
|
page = self.get_page(YandexMainPage)
|
||||||
|
|
||||||
|
def action():
|
||||||
|
page.search_input.send_keys(random.choice(words))
|
||||||
|
|
||||||
|
self.check_by_screenshot(page.search_field, action)
|
||||||
29
screenshot_tests/utils/common.py
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
import pytest
|
||||||
|
import os
|
||||||
|
from screenshot_tests.page_objects.elements import PageBoundGeneric
|
||||||
|
from conftest import Config
|
||||||
|
from typing import Type
|
||||||
|
|
||||||
|
|
||||||
|
class TestCase:
|
||||||
|
"""Base class for all tests."""
|
||||||
|
|
||||||
|
@pytest.fixture(autouse=True)
|
||||||
|
def set_driver(self, driver):
|
||||||
|
self.driver = driver
|
||||||
|
|
||||||
|
@pytest.fixture(autouse=True)
|
||||||
|
def configure(self, request):
|
||||||
|
self.base_url = request.config.getoption(Config.BASE_URL)
|
||||||
|
self.staging = request.config.getoption(Config.STAGING)
|
||||||
|
|
||||||
|
def get_page(self, page_class: Type[PageBoundGeneric]) -> PageBoundGeneric:
|
||||||
|
"""Create instance of web page and return it."""
|
||||||
|
path = page_class.path
|
||||||
|
|
||||||
|
if path is None:
|
||||||
|
raise TypeError(f"Path in {page_class} is None!")
|
||||||
|
|
||||||
|
page = page_class(self.driver)
|
||||||
|
self.driver.get(os.path.join(self.base_url, path))
|
||||||
|
return page
|
||||||
143
screenshot_tests/utils/screenshots.py
Normal file
@@ -0,0 +1,143 @@
|
|||||||
|
import pytest
|
||||||
|
import time
|
||||||
|
import logging
|
||||||
|
import allure
|
||||||
|
|
||||||
|
from screenshot_tests.page_objects.custom_web_element import CustomWebElement
|
||||||
|
from urllib.parse import urlparse
|
||||||
|
from screenshot_tests.page_objects.elements import Locators
|
||||||
|
from screenshot_tests.utils import common
|
||||||
|
from screenshot_tests.image_proccessing.image_processor import ImageProcessor
|
||||||
|
from typing import Tuple
|
||||||
|
from PIL import Image
|
||||||
|
|
||||||
|
|
||||||
|
# https://github.com/allure-framework/allure2/tree/master/plugins/screen-diff-plugin
|
||||||
|
@allure.label('testType', 'screenshotDiff')
|
||||||
|
class TestCase(common.TestCase):
|
||||||
|
"""Base class for all screenshot tests."""
|
||||||
|
|
||||||
|
BODY_LOCATOR = (Locators.CSS_SELECTOR, "body")
|
||||||
|
|
||||||
|
@pytest.fixture(autouse=True)
|
||||||
|
def screenshot_prepare(self):
|
||||||
|
self.image_processor = ImageProcessor()
|
||||||
|
# количество попыток для снятия скриншота
|
||||||
|
self.attempts = 5
|
||||||
|
|
||||||
|
def _scroll(self, x: int, y: int):
|
||||||
|
scroll_string = f"window.scrollTo({x}, {y})"
|
||||||
|
self.driver.execute_script(scroll_string)
|
||||||
|
time.sleep(0.2)
|
||||||
|
logging.info(f"Scroll to «{scroll_string}»")
|
||||||
|
|
||||||
|
def _make_screenshot_whole_page(self):
|
||||||
|
total_width = self.driver.execute_script("return document.body.offsetWidth")
|
||||||
|
total_height = self.driver.execute_script("return document.body.parentNode.scrollHeight")
|
||||||
|
viewport_width = self.driver.execute_script("return document.body.clientWidth")
|
||||||
|
viewport_height = self.driver.execute_script("return window.innerHeight")
|
||||||
|
screenshots = []
|
||||||
|
offset = 0
|
||||||
|
assert viewport_width == total_width, "Ширина вьюпорта, и ширина экрана должны совпадать"
|
||||||
|
|
||||||
|
self._scroll(0, 0)
|
||||||
|
while offset <= total_height:
|
||||||
|
screenshots.append(self.driver.get_screenshot_as_png())
|
||||||
|
offset += viewport_height
|
||||||
|
self._scroll(0, offset)
|
||||||
|
|
||||||
|
return self.image_processor.paste(screenshots)
|
||||||
|
|
||||||
|
def _get_coords_by_locator(self, by, locator) -> Tuple[int, int, int, int]:
|
||||||
|
# После того, как дождались видимости элемента, ждем еще 2 секунды, чтобы точно завершились разные анимации
|
||||||
|
time.sleep(2)
|
||||||
|
el = self.driver.find_element(by, locator)
|
||||||
|
location = el.location
|
||||||
|
size = el.size
|
||||||
|
x = location["x"]
|
||||||
|
y = location["y"]
|
||||||
|
width = location["x"] + size['width']
|
||||||
|
height = location["y"] + size['height']
|
||||||
|
return x * 2, y * 2, width * 2, height * 2
|
||||||
|
|
||||||
|
def _get_element_screenshot(self, by, locator, action, finalize) \
|
||||||
|
-> Tuple[Image.Image, Tuple[int, int, int, int]]:
|
||||||
|
"""Get screenshot of element.
|
||||||
|
|
||||||
|
Can't use session/{sessionId}/element/{elementId}/screenshot because it's available only in Edge
|
||||||
|
https://stackoverflow.com/questions/36084257/im-trying-to-take-a-screenshot-of-an-element-with-selenium-webdriver-but-unsup
|
||||||
|
"""
|
||||||
|
if callable(action):
|
||||||
|
action()
|
||||||
|
|
||||||
|
coordinates = self._get_coords_by_locator(by, locator)
|
||||||
|
screen = self._make_screenshot_whole_page()
|
||||||
|
logging.info(f"element: {locator}, coordinates: {coordinates}")
|
||||||
|
|
||||||
|
if callable(finalize):
|
||||||
|
finalize()
|
||||||
|
|
||||||
|
return screen.crop(coordinates), coordinates
|
||||||
|
|
||||||
|
def _get_diff(self, element: CustomWebElement, action=None, full_page=False, finalize=None):
|
||||||
|
"""Get screenshot from test environment and compare with production.
|
||||||
|
|
||||||
|
:param element: element for check (instance of CustomWebElement)
|
||||||
|
:param action: callback executed before making screenshot. Use it when need prepare page for screenshot.
|
||||||
|
:param full_page: ignore element, and compare whole page.
|
||||||
|
:param finalize: callback executed after screenshot.
|
||||||
|
"""
|
||||||
|
if full_page:
|
||||||
|
by, locator = self.BODY_LOCATOR
|
||||||
|
else:
|
||||||
|
by, locator = element.by, element.locator
|
||||||
|
|
||||||
|
saved_url = urlparse(self.driver.current_url)
|
||||||
|
# noinspection PyProtectedMember
|
||||||
|
prod_url = saved_url._replace(netloc=urlparse(self.staging).netloc)
|
||||||
|
|
||||||
|
# Открываем странички пока размеры элементов на них не совпадут
|
||||||
|
coords_equal = False
|
||||||
|
attempts = 0
|
||||||
|
while not coords_equal and attempts < self.attempts:
|
||||||
|
logging.info(f'Try make screenshots. Attempts: {attempts}')
|
||||||
|
|
||||||
|
# На текущей странице делаем первый скриншот
|
||||||
|
first_image, coords_test = self._get_element_screenshot(by, locator, action, finalize)
|
||||||
|
|
||||||
|
# Теперь делаем скриншот в проде
|
||||||
|
self.driver.get(prod_url.geturl())
|
||||||
|
second_image, coords_prod = self._get_element_screenshot(by, locator, action, finalize)
|
||||||
|
|
||||||
|
# Возращаемся на тестовый стенд. Всегда нужно возвращаться на тестовый стенд. На это завязаны тесты и отчеты
|
||||||
|
self.driver.get(saved_url.geturl())
|
||||||
|
|
||||||
|
# Если размеры элементов на странице не совпали, и выбраны не все попытки, пробуем снова
|
||||||
|
attempts += 1
|
||||||
|
# По размеру блока, оставим на случай, если по координатам способ будет не работать не очень
|
||||||
|
x1, y1, x2, y2 = coords_test
|
||||||
|
x_1, y_1, x_2, y_2 = coords_prod
|
||||||
|
size_test = round(((x2 - x1) ** 2 + (y2 - y1) ** 2) ** 0.5)
|
||||||
|
size_prod = round(((x_2 - x_1) ** 2 + (y_2 - y_1) ** 2) ** 0.5)
|
||||||
|
logging.info(f"Coords test: {coords_test}, coords prod: {coords_prod}")
|
||||||
|
logging.info(f"Size test: {size_test}, size prod: {size_prod}")
|
||||||
|
coords_equal = size_prod == size_test
|
||||||
|
|
||||||
|
# noinspection PyUnboundLocalVariable
|
||||||
|
diff, result, first, second = self.image_processor.get_images_diff(first_image, second_image)
|
||||||
|
|
||||||
|
# Для добавления в отчет (https://github.com/allure-framework/allure2/tree/master/plugins/screen-diff-plugin)
|
||||||
|
allure.attach(result, "diff", allure.attachment_type.PNG)
|
||||||
|
allure.attach(first, "actual", allure.attachment_type.PNG)
|
||||||
|
allure.attach(second, "expected", allure.attachment_type.PNG)
|
||||||
|
|
||||||
|
return diff, saved_url, prod_url
|
||||||
|
|
||||||
|
def get_diff(self, *args, **kwargs):
|
||||||
|
diff, _, _ = self._get_diff(*args, **kwargs)
|
||||||
|
return diff
|
||||||
|
|
||||||
|
def check_by_screenshot(self, element: CustomWebElement, *args, **kwargs):
|
||||||
|
diff, saved_url, prod_url = self._get_diff(element, *args, **kwargs)
|
||||||
|
info = element.description
|
||||||
|
assert diff == 0, f"{info} отличается на страницах:\n{saved_url.geturl()}\nи\n{prod_url.geturl()}"
|
||||||