[pitivi] Implement UI testing with Dogtail
- From: Jean-FranÃois Fortin Tam <jfft src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [pitivi] Implement UI testing with Dogtail
- Date: Wed, 25 Jul 2012 11:55:57 +0000 (UTC)
commit d44d440fba85c35c9a453fe6a3eb15e5e514e204
Author: Matas Brazdeikis <matas brazdeikis lt>
Date: Fri Jul 20 17:00:33 2012 -0400
Implement UI testing with Dogtail
This provides a basic set of tests to simulate user interaction.
tests/dogtail_scripts/helper_functions.py | 25 ++
tests/dogtail_scripts/test_base.py | 41 +++
tests/dogtail_scripts/test_clipproperties.py | 83 ++++++
.../dogtail_scripts/test_dialogs_clipmediaprops.py | 59 +++++
tests/dogtail_scripts/test_dialogs_prefs.py | 50 ++++
.../dogtail_scripts/test_dialogs_startupwizard.py | 19 ++
tests/dogtail_scripts/test_effects.py | 79 ++++++
tests/dogtail_scripts/test_help_func.py | 125 +++++++++
tests/dogtail_scripts/test_medialibrary.py | 30 +++
tests/dogtail_scripts/test_project.py | 267 ++++++++++++++++++++
tests/dogtail_scripts/test_timeline.py | 235 +++++++++++++++++
tests/samples/1sec_simpsons_trailer.mp4 | Bin 0 -> 232417 bytes
tests/samples/flat_colour4_1600x1200.jpg | Bin 0 -> 23048 bytes
tests/samples/flat_colour5_1600x1200.jpg | Bin 0 -> 23048 bytes
14 files changed, 1013 insertions(+), 0 deletions(-)
---
diff --git a/tests/dogtail_scripts/helper_functions.py b/tests/dogtail_scripts/helper_functions.py
new file mode 100644
index 0000000..0a30ad9
--- /dev/null
+++ b/tests/dogtail_scripts/helper_functions.py
@@ -0,0 +1,25 @@
+import os
+from dogtail.predicate import GenericPredicate
+import dogtail.rawinput
+from time import sleep
+
+
+def improved_drag(fromcord, tocord, middle=[], absolute=True, moveAround=True):
+ dogtail.rawinput.press(fromcord[0], fromcord[1])
+ if moveAround:
+ dogtail.rawinput.relativeMotion(5, 5)
+ dogtail.rawinput.relativeMotion(-5, -5)
+ if absolute:
+ fun = dogtail.rawinput.absoluteMotion
+ else:
+ fun = dogtail.rawinput.relativeMotion
+ for mid in middle:
+ fun(mid[0], mid[1])
+ if moveAround:
+ dogtail.rawinput.relativeMotion(5, 5)
+ dogtail.rawinput.relativeMotion(-5, -5)
+ dogtail.rawinput.absoluteMotion(tocord[0], tocord[1])
+ if moveAround:
+ dogtail.rawinput.relativeMotion(5, 5)
+ dogtail.rawinput.relativeMotion(-5, -5)
+ dogtail.rawinput.release(tocord[0], tocord[1])
diff --git a/tests/dogtail_scripts/test_base.py b/tests/dogtail_scripts/test_base.py
new file mode 100644
index 0000000..5c1e5c4
--- /dev/null
+++ b/tests/dogtail_scripts/test_base.py
@@ -0,0 +1,41 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+import unittest
+import os
+from dogtail.predicate import GenericPredicate
+
+
+class BaseDogTail(unittest.TestCase):
+ def setUp(self):
+ # Force the locale/language to English.
+ # Otherwise we won't be able to grab the right widgets.
+ os.environ["LC_ALL"] = 'C'
+ # Try to speed up UI interaction a little
+ from dogtail.config import config
+ config.load({'actionDelay': 0.1,
+ 'typingDelay': 0.02,
+ 'runTimeout': 1,
+ 'searchCutoffCount': 5,
+ 'defaultDelay': 0.1})
+ from dogtail.utils import run
+ from dogtail.tree import root
+ # Setting appName is critically important here.
+ # Otherwise it will try to look for "bin/pitivi" through AT-SPI and fail,
+ # making the tests take ages to start up.
+ self.pid = run('bin/pitivi', dumb=False, appName="pitivi")
+ self.pitivi = root.application('pitivi')
+ self.menubar = self.pitivi.child(roleName='menu bar')
+ try:
+ self.unlink
+ except AttributeError:
+ self.unlink = []
+
+ def tearDown(self, clean=True):
+ # Try to kill pitivi before leaving test
+ os.system("kill -9 %i" % self.pid)
+ if clean:
+ for filename in self.unlink:
+ try:
+ os.unlink(filename)
+ except:
+ None
diff --git a/tests/dogtail_scripts/test_clipproperties.py b/tests/dogtail_scripts/test_clipproperties.py
new file mode 100644
index 0000000..22233e6
--- /dev/null
+++ b/tests/dogtail_scripts/test_clipproperties.py
@@ -0,0 +1,83 @@
+#!/usr/bin/env python
+from test_help_func import HelpFunc
+from dogtail.predicate import GenericPredicate
+import dogtail.rawinput
+from time import sleep
+
+
+class ClipTransforamtionTest(HelpFunc):
+ def test_transformation_options(self):
+ #Load sample
+ sample = self.import_media()
+ self.insert_clip(sample)
+
+ timeline = self.get_timeline()
+ clippos = []
+ clippos.append((timeline.position[0] + 20, timeline.position[1] + 20))
+ clippos.append((timeline.position[0] + timeline.size[0] / 2, timeline.position[1] + 20))
+ dogtail.rawinput.click(clippos[0][0], clippos[0][1])
+
+ conftab = self.pitivi.tab("Clip configuration")
+ conftab.click()
+ conftab.child(name="Transformation", roleName="toggle button").click()
+ #Just try changing values
+ #Test slider
+ self.assertEqual(conftab.child(roleName="slider").value, 1)
+ conftab.child(roleName="slider").click()
+ self.assertNotEqual(conftab.child(roleName="slider").value, 1)
+
+ #Test position
+ spinb = conftab.child(roleName="panel", name="Position").findChildren(GenericPredicate(roleName="spin button"))
+ self.assertEqual(len(spinb), 2)
+ spinb[0].text = "0.3"
+ spinb[1].text = "0.2"
+
+ #Test size
+ spinb = conftab.child(roleName="panel", name="Size").findChildren(GenericPredicate(roleName="spin button"))
+ self.assertEqual(len(spinb), 2)
+ spinb[0].text = "0.4"
+ spinb[1].text = "0.1"
+
+ #Test crop
+ spinb = conftab.child(roleName="panel", name="Crop").findChildren(GenericPredicate(roleName="spin button"))
+ self.assertEqual(len(spinb), 4)
+ spinb[0].text = "0.05"
+ spinb[1].text = "0.12"
+ spinb[2].text = "0.14"
+ spinb[3].text = "0.07"
+
+ #Click second clip, look that settings not changed(not linked)
+ dogtail.rawinput.click(clippos[1][0], clippos[1][1])
+ self.assertEqual(conftab.child(roleName="slider").value, 1.0)
+
+ #Click back, look if settings saved
+ dogtail.rawinput.click(clippos[0][0], clippos[0][1])
+ self.assertNotEqual(conftab.child(roleName="slider").value, 1.0)
+
+ self.assertNotNone(self.search_by_text("0.3", conftab.child(roleName="panel", name="Position")))
+ self.assertNotNone(self.search_by_text("0.2", conftab.child(roleName="panel", name="Position")))
+
+ self.assertNotNone(self.search_by_text("0.4", conftab.child(roleName="panel", name="Size")))
+ self.assertNotNone(self.search_by_text("0.1", conftab.child(roleName="panel", name="Size")))
+
+ self.assertNotNone(self.search_by_text("0.05", conftab.child(roleName="panel", name="Crop")))
+ self.assertNotNone(self.search_by_text("0.12", conftab.child(roleName="panel", name="Crop")))
+ self.assertNotNone(self.search_by_text("0.14", conftab.child(roleName="panel", name="Crop")))
+ self.assertNotNone(self.search_by_text("0.07", conftab.child(roleName="panel", name="Crop")))
+
+ #Push clear
+ conftab.child(roleName="scroll bar").value = 140
+ conftab.button("Clear")
+
+ self.assertEqual(conftab.child(roleName="slider").value, 1.0)
+
+ self.assertNone(self.search_by_text("0.3", conftab.child(roleName="panel", name="Position")))
+ self.assertNone(self.search_by_text("0.2", conftab.child(roleName="panel", name="Position")))
+
+ self.assertNone(self.search_by_text("0.4", conftab.child(roleName="panel", name="Size")))
+ self.assertNone(self.search_by_text("0.1", conftab.child(roleName="panel", name="Size")))
+
+ self.assertNone(self.search_by_text("0.05", conftab.child(roleName="panel", name="Crop")))
+ self.assertNone(self.search_by_text("0.12", conftab.child(roleName="panel", name="Crop")))
+ self.assertNone(self.search_by_text("0.14", conftab.child(roleName="panel", name="Crop")))
+ self.assertNone(self.search_by_text("0.07", conftab.child(roleName="panel", name="Crop")))
diff --git a/tests/dogtail_scripts/test_dialogs_clipmediaprops.py b/tests/dogtail_scripts/test_dialogs_clipmediaprops.py
new file mode 100644
index 0000000..1853b47
--- /dev/null
+++ b/tests/dogtail_scripts/test_dialogs_clipmediaprops.py
@@ -0,0 +1,59 @@
+#!/usr/bin/env python
+from test_help_func import HelpFunc
+from dogtail.tree import SearchError
+from dogtail.predicate import GenericPredicate, IsATextEntryNamed
+
+
+class DialogsClipMediaPropsTest(HelpFunc):
+ def test_clip_props_dialog(self):
+ sample = self.import_media("flat_colour1_640x480.png")
+ sample.click(3)
+ buttons = self.pitivi.findChildren(GenericPredicate(name="Clip Properties..."))
+ buttons[1].click()
+
+ #Check if we have real info, can't check if in correct place.
+ dialog = self.pitivi.child(name="Clip Properties", roleName="dialog")
+ labels = {"640", "480"}
+ real_labels = set([])
+ for label in dialog.findChildren(GenericPredicate(roleName="label")):
+ real_labels.add(label.text)
+ self.assertEqual(len(labels.difference(real_labels)), 0, "Not all info is displayed")
+ self.assertFalse(dialog.child(name="Audio:", roleName="panel").showing)
+ dialog.child(name="Cancel").click()
+ sample.deselect()
+
+ sample = self.import_media()
+ sample.select()
+ self.menubar.menu("Library").click()
+ self.menubar.menuItem("Clip Properties...").click()
+
+ #Check if we have real info, can't check if in correct place.
+ dialog = self.pitivi.child(name="Clip Properties", roleName="dialog")
+ labels = {"1280", "544", "23.976 fps", "Square", "Stereo", "48 KHz", "16 bit"}
+ real_labels = set([])
+ for label in dialog.findChildren(GenericPredicate(roleName="label")):
+ real_labels.add(label.text)
+ self.assertEqual(len(labels.difference(real_labels)), 0, "Not all info is displayed")
+
+ #Uncheck frame rate
+ dialog.child(name="Frame rate:").click()
+ dialog.child(name="Apply to project").click()
+
+ #Check if correctly applied
+ self.menubar.menu("Edit").click()
+ self.pitivi.child(name="Project Settings", roleName="menu item").click()
+ dialog = self.pitivi.child(name="Project Settings", roleName="dialog")
+
+ children = dialog.findChildren(IsATextEntryNamed(""))
+ childtext = {}
+ for child in children:
+ childtext[child.text] = child
+
+ self.assertIn("25:1", childtext)
+ self.assertIn("1:1", childtext)
+ children = dialog.findChildren(GenericPredicate(roleName="spin button"))
+ spintext = {}
+ for child in children:
+ spintext[child.text] = child
+ self.assertIn("1280", spintext)
+ self.assertIn("544", spintext)
diff --git a/tests/dogtail_scripts/test_dialogs_prefs.py b/tests/dogtail_scripts/test_dialogs_prefs.py
new file mode 100644
index 0000000..9181443
--- /dev/null
+++ b/tests/dogtail_scripts/test_dialogs_prefs.py
@@ -0,0 +1,50 @@
+#!/usr/bin/env python
+from test_help_func import HelpFunc
+from dogtail.tree import SearchError
+import dogtail.rawinput
+
+
+class DialogsPreferencesTest(HelpFunc):
+ def test_pref_dialog(self):
+ dogtail.rawinput.pressKey("Esc")
+ self.menubar.menu("Edit").click()
+ self.menubar.child(name="Preferences", roleName="menu item").click()
+ dialog = self.pitivi.child(name="Preferences", roleName="dialog")
+ dialog.child("Reset to Factory Settings", roleName="push button").click()
+
+ #Try choose the font
+ dialog.child(name="Sans", roleName="label").click()
+ fontchooser = self.pitivi.child(name="Pick a Font", roleName="fontchooser")
+ fontchooser.child(name="Serif").click()
+ fontchooser.child(name="OK", roleName="push button").click()
+
+ #Try choose thumbnail gap
+ dialog.child(roleName="spin button").text = "12"
+
+ #Restart pitivi, look if saved
+ dialog.button("Close")
+
+ self.tearDown()
+ self.setUp()
+
+ dogtail.rawinput.pressKey("Esc")
+ self.menubar.menu("Edit").click()
+ self.menubar.child(name="Preferences", roleName="menu item").click()
+ dialog = self.pitivi.child(name="Preferences", roleName="dialog")
+
+ #Just search of such item
+ try:
+ dialog.child(name="Serif", roleName="label")
+ except SearchError:
+ self.fail("Font is not saved")
+ self.assertEqual(dialog.child(roleName="spin button").text, 12)
+
+ #Check revert
+ dialog.child(roleName="spin button").text = "7"
+ dialog.child("Revert", roleName="push button").click()
+ self.assertEqual(dialog.child(roleName="spin button").text, 12, "Spacing is not reverted")
+
+ #Check reset to factory settings
+ dialog.child("Reset to Factory Settings", roleName="push button").click()
+ dialog.child(name="Sans", roleName="label")
+ self.assertEqual(dialog.child(roleName="spin button").text, 5, "Spacing is not reseted")
diff --git a/tests/dogtail_scripts/test_dialogs_startupwizard.py b/tests/dogtail_scripts/test_dialogs_startupwizard.py
new file mode 100644
index 0000000..7ba0545
--- /dev/null
+++ b/tests/dogtail_scripts/test_dialogs_startupwizard.py
@@ -0,0 +1,19 @@
+#!/usr/bin/env python
+from test_help_func import HelpFunc
+from time import time, sleep
+
+
+class DialogsStartupWizardTest(HelpFunc):
+ def test_welcome(self):
+ filename = "test_project%i.xptv" % time()
+ #Save project
+ self.pitivi.child(name="New", roleName='push button').click()
+ self.pitivi.child(name="OK", roleName="push button").click()
+ self.saveProject("/tmp/" + filename)
+ sleep(1)
+ #Hacky, but we need to open once more
+ self.tearDown(clean=False)
+ self.setUp()
+ welcome = self.pitivi.child(name="Welcome", roleName="frame")
+ #We expect that just saved project will be in welcome window
+ welcome.child(name=filename)
diff --git a/tests/dogtail_scripts/test_effects.py b/tests/dogtail_scripts/test_effects.py
new file mode 100644
index 0000000..aa88b60
--- /dev/null
+++ b/tests/dogtail_scripts/test_effects.py
@@ -0,0 +1,79 @@
+#!/usr/bin/env python
+from test_help_func import HelpFunc
+from helper_functions import improved_drag
+import dogtail.rawinput
+
+
+class EffectLibraryTest(HelpFunc):
+ def test_effect_library(self):
+ #Load sample
+ self.import_media()
+ tab = self.pitivi.tab("Effect Library")
+ tab.click()
+ search = tab.textentry("")
+ iconview = tab.child(roleName="layered pane")
+ combotypes = tab.child(name="All effects", roleName="combo box")
+ #Some test of video effects and search
+ search.text = "Crop"
+ self.assertEqual(len(iconview.children), 3)
+ combotypes.click()
+ tab.menuItem("Colors").click()
+ self.assertEqual(len(iconview.children), 0)
+ combotypes.click()
+ tab.menuItem("Geometry").click()
+ self.assertEqual(len(iconview.children), 3)
+
+ #Audio effects
+ tab.child(name="Video effects", roleName="combo box").click()
+ tab.menuItem("Audio effects").click()
+ search.text = "Equa"
+ #Titles plus 3 plugins, two collumns = 8
+ self.assertEqual(len(tab.child(roleName="table").children), 8)
+
+ def help_test_effect_drag(self):
+ sample = self.import_media()
+ self.insert_clip(sample)
+ timeline = self.get_timeline()
+ clippos = (timeline.position[0] + 20, timeline.position[1] + 20)
+
+ tab = self.pitivi.tab("Effect Library")
+ tab.click()
+ conftab = self.pitivi.tab("Clip configuration")
+ conftab.click()
+ table = conftab.child(roleName="table")
+
+ dogtail.rawinput.click(clippos[0], clippos[1])
+ self.assertTrue(table.sensitive)
+ #No effects added
+ self.assertEqual(len(table.children), 3)
+
+ center = lambda obj: (obj.position[0] + obj.size[0] / 2, obj.position[1] + obj.size[1] / 2)
+ icon = self.search_by_text("Agingtv ", tab, roleName="icon")
+
+ #Drag video effect on the clip
+ improved_drag(center(icon), clippos)
+ self.assertEqual(len(table.children), 6)
+ #Drag video effect to the table
+ icon = self.search_by_text("3Dflippo", tab, roleName="icon")
+ improved_drag(center(icon), center(table))
+ self.assertEqual(len(table.children), 9)
+
+ #Drag audio effect on the clip
+ tab.child(name="Video effects", roleName="combo box").click()
+ tab.menuItem("Audio effects").click()
+ effect = tab.child(name="Amplifier")
+ improved_drag(center(effect), clippos)
+ self.assertEqual(len(table.children), 12)
+
+ #Drag audio effect on the table
+ effect = tab.child(name="Audiokaraoke")
+ improved_drag(center(effect), center(table))
+ self.assertEqual(len(table.children), 15)
+
+ def test_change_effect_settings(self):
+ self.help_test_effect_drag()
+ conftab = self.pitivi.tab("Clip configuration")
+ conftab.child(roleName="table").child(name="audioamplify").click()
+ eftab = conftab.child(name="Effects", roleName="toggle button")
+ eftab.child(name="Normal clipping (default)", roleName="combo box")
+ eftab.child(roleName="spin button").text = "2"
diff --git a/tests/dogtail_scripts/test_help_func.py b/tests/dogtail_scripts/test_help_func.py
new file mode 100644
index 0000000..66a0705
--- /dev/null
+++ b/tests/dogtail_scripts/test_help_func.py
@@ -0,0 +1,125 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+import unittest
+import os
+from dogtail.predicate import GenericPredicate
+from test_base import BaseDogTail
+import dogtail.rawinput
+from time import sleep
+from pyatspi import Registry as registry
+from pyatspi import (KEY_SYM, KEY_PRESS, KEY_PRESSRELEASE, KEY_RELEASE)
+
+
+class HelpFunc(BaseDogTail):
+ def saveProject(self, url=None, saveAs=True):
+ self.menubar.menu("Project").click()
+ if saveAs:
+ #FIXME: cant get working with searching for Save Asâ
+ self.menubar.menu("Project").children[4].click()
+ saveas = self.pitivi.child(roleName='dialog')
+ saveas.child(roleName='text').text = url
+ #Click the Save button.
+ saveas.button('Save').click()
+ #Save for deleting afterwards
+ self.unlink.append(url)
+ else:
+ #Just save
+ self.menubar.menu("Project").menuItem("Save").click()
+
+ def loadProject(self, url, save=False):
+ self.menubar.menu("Project").click()
+ self.menubar.menu("Project").children[2].click()
+ load = self.pitivi.child(roleName='dialog')
+ load.child(name="Type a file name", roleName="toggle button").click()
+ load.child(roleName='text').text = url
+ load.button('Open').click()
+ try:
+ if save:
+ load.child(name="Close without saving", roleName="push button")
+ except:
+ return
+
+ def search_by_text(self, text, parent, name=None, roleName=None):
+ children = parent.findChildren(GenericPredicate(roleName=roleName,
+ name=name))
+ searched = None
+ for child in children:
+ if child.text == text:
+ searched = child
+ return searched
+
+ def insert_clip(self, icon, n=1):
+ icon.select()
+ lib = self.menubar.menu("Library")
+ insert = lib.child("Insert at End of Timeline")
+ for i in range(n):
+ sleep(0.3)
+ lib.click()
+ sleep(0.1)
+ insert.click()
+ icon.deselect()
+
+ def import_media(self, filename="1sec_simpsons_trailer.mp4"):
+ #Just try search for object without retries
+ dogtail.rawinput.pressKey("Esc")
+ self.pitivi.child(name="Import Files...",
+ roleName="push button").click()
+ add = self.pitivi.child(roleName='dialog')
+ textf = add.findChildren(GenericPredicate(roleName="text"))
+ if len(textf) == 0:
+ add.child(name="Type a file name", roleName="toggle button").click()
+ filepath = os.path.realpath(__file__).split("dogtail_scripts/test_help_func.py")[0]
+ filepath += "samples/" + filename
+ add.child(roleName='text').text = filepath
+ add.button('Add').click()
+ libtab = self.pitivi.tab("Media Library")
+ for i in range(5):
+ icons = libtab.findChildren(GenericPredicate(roleName="icon"))
+ sample = None
+ for icon in icons:
+ if icon.text == filename:
+ sample = icon
+ if sample is not None:
+ break
+ sleep(0.5)
+ self.assertIsNotNone(sample)
+ return sample
+
+ def import_media_multiple(self, files):
+ dogtail.rawinput.pressKey("Esc")
+ self.pitivi.child(name="Import Files...",
+ roleName="push button").click()
+ add = self.pitivi.child(roleName='dialog')
+ textf = add.findChildren(GenericPredicate(roleName="text"))
+ if len(textf) == 0:
+ add.child(name="Type a file name", roleName="toggle button").click()
+ filepath = os.path.realpath(__file__).split("dogtail_scripts/test_help_func.py")[0]
+ filepath += "samples/"
+ add.child(roleName='text').click()
+ add.child(roleName='text').text = filepath
+ dogtail.rawinput.pressKey("Enter")
+ #Now select them
+ code = dogtail.rawinput.keyNameToKeyCode("Control_L")
+ registry.generateKeyboardEvent(code, None, KEY_PRESS)
+ for f in files:
+ sleep(1)
+ add.child(name=f).click()
+ registry.generateKeyboardEvent(code, None, KEY_RELEASE)
+ add.button('Add').click()
+ libtab = self.pitivi.tab("Media Library")
+ samples = []
+ for i in range(5):
+ icons = libtab.findChildren(GenericPredicate(roleName="icon"))
+ for icon in icons:
+ for f in files:
+ if icon.text == f:
+ samples.append(icon)
+ files.remove(f)
+ if len(files) == 0:
+ break
+ sleep(0.5)
+ return samples
+
+ def get_timeline(self):
+ #TODO: found better way to identify
+ return self.pitivi.children[0].children[0].children[2].children[1].children[3]
diff --git a/tests/dogtail_scripts/test_medialibrary.py b/tests/dogtail_scripts/test_medialibrary.py
new file mode 100644
index 0000000..dd93b4c
--- /dev/null
+++ b/tests/dogtail_scripts/test_medialibrary.py
@@ -0,0 +1,30 @@
+#!/usr/bin/env python
+from test_help_func import HelpFunc
+
+
+class MediaLibraryTest(HelpFunc):
+ def test_medialibrary(self):
+ #Load few samples
+ samples = []
+ samples.append(self.import_media("flat_colour1_640x480.png"))
+ samples.append(self.import_media("flat_colour2_640x480.png"))
+ samples.append(self.import_media("flat_colour3_320x180.png"))
+ self.insert_clip(samples[0])
+ self.insert_clip(samples[2])
+
+ self.menubar.menu("Library").click()
+ self.menubar.menu("Library").menuItem("Select Unused Media").click()
+ self.assertFalse(samples[0].isSelected)
+ self.assertTrue(samples[1].isSelected)
+ self.assertFalse(samples[2].isSelected)
+
+ tab = self.pitivi.tab("Media Library")
+ iconview = tab.child(roleName="layered pane")
+ self.assertEqual(len(iconview.children), 3)
+ search = tab.textentry("")
+ search.text = "colour2"
+ self.assertEqual(len(iconview.children), 1)
+ search.text = "640"
+ self.assertEqual(len(iconview.children), 2)
+ search.text = ""
+ self.assertEqual(len(iconview.children), 3)
diff --git a/tests/dogtail_scripts/test_project.py b/tests/dogtail_scripts/test_project.py
new file mode 100644
index 0000000..94c4ade
--- /dev/null
+++ b/tests/dogtail_scripts/test_project.py
@@ -0,0 +1,267 @@
+#!/usr/bin/env python
+from test_help_func import HelpFunc
+from dogtail.predicate import IsATextEntryNamed, GenericPredicate
+from time import time, sleep
+import os
+
+
+class ProjectPropertiesTest(HelpFunc):
+ def test_settings_video(self):
+ #Just create new project
+ self.pitivi.child(name="New", roleName='push button').click()
+
+ #Play with project settings, look if they are correctly represented
+ dialog = self.pitivi.child(name="Project Settings", roleName="dialog")
+ video = self.pitivi.tab("Video")
+
+ #Test presets
+ video.child(name="720p24", roleName="table cell").click()
+ children = video.findChildren(IsATextEntryNamed(""))
+ childtext = {}
+ for child in children:
+ childtext[child.text] = child
+
+ self.assertIn("1:1", childtext)
+ self.assertIn("24M", childtext)
+ self.assertIn("16:9", childtext)
+
+ children = video.findChildren(GenericPredicate(roleName="spin button"))
+ spintext = {}
+ for child in children:
+ spintext[child.text] = child
+ self.assertIn("1280", spintext)
+ self.assertIn("720", spintext)
+
+ #Test frame rate combinations, link button
+ frameCombo = video.child(name="23.976 fps", roleName="combo box")
+ frameText = childtext["24M"]
+ frameCombo.click()
+ video.child(name="120 fps", roleName="menu item").click()
+ self.assertEqual(frameText.text, "120:1")
+ frameText.click()
+ frameText.typeText("0")
+ video.child(name="12 fps", roleName="combo box")
+
+ #Test pixel and display ascpect ratio
+ pixelCombo = video.child(name="Square", roleName="combo box")
+ pixelText = childtext["1:1"]
+ displayCombo = video.child(name="DV Widescreen (16:9)",
+ roleName="combo box")
+ displayText = childtext["16:9"]
+
+ pixelCombo.click()
+ video.child(name="576p", roleName="menu item").click()
+ self.assertEqual(pixelCombo.combovalue, "576p")
+ self.assertEqual(pixelText.text, "12:11")
+ #self.assertEqual(displayCombo.combovalue, "")
+ self.assertEqual(displayText.text, "64:33")
+
+ pixelText.doubleClick()
+ pixelText.click()
+ pixelText.typeText("3:4")
+ #self.assertEqual(pixelCombo.combovalue, "")
+ self.assertEqual(pixelText.text, "3:4")
+ self.assertEqual(displayCombo.combovalue, "Standard (4:3)")
+ self.assertEqual(displayText.text, "4:3")
+
+ video.child(name="Display aspect ratio",
+ roleName="radio button").click()
+ displayCombo.click()
+ video.child(name="Cinema (1.37)", roleName="menu item").click()
+ #self.assertEqual(pixelCombo.combovalue, "")
+ self.assertEqual(pixelText.text, "99:128")
+ self.assertEqual(displayCombo.combovalue, "Cinema (1.37)")
+ self.assertEqual(displayText.text, "11:8")
+
+ displayText.doubleClick()
+ displayText.click()
+ displayText.typeText("37:20")
+ #self.assertEqual(pixelCombo.combovalue, "")
+ self.assertEqual(pixelText.text, "333:320")
+ self.assertEqual(displayCombo.combovalue, "Cinema (1.85)")
+ self.assertEqual(displayText.text, "37:20")
+
+ #Test size spin buttons
+ spin = video.findChildren(GenericPredicate(roleName="spin button"))
+ oldtext = spin[1].text
+ spin[0].doubleClick()
+ spin[0].typeText("1000")
+ self.assertEqual(spin[1].text, oldtext)
+ spin[1].doubleClick()
+ spin[1].typeText("2000")
+ video.child(name="Link").click()
+ spin[1].doubleClick()
+ spin[1].typeText("1000")
+ spin[0].click()
+ self.assertEqual(spin[0].text, "500")
+
+ #Create project, test saving without any object
+ self.pitivi.child(name="OK", roleName="push button").click()
+ self.saveProject("/tmp/settings.xptv")
+ #Load project and test settings
+ self.loadProject("/tmp/settings.xptv")
+ self.pitivi.menu("Edit").click()
+ self.pitivi.child(name="Project Settings", roleName="menu item").click()
+
+ video = self.pitivi.tab("Video")
+
+ children = video.findChildren(IsATextEntryNamed(""))
+ childtext = {}
+ for child in children:
+ childtext[child.text] = child
+
+ self.assertIn("333:320", childtext, "Pixel aspect ration not saved")
+ self.assertIn("37:20", childtext, "Display aspect ratio not saved")
+
+ children = video.findChildren(GenericPredicate(roleName="spin button"))
+ spintext = {}
+ for child in children:
+ spintext[child.text] = child
+ self.assertIn("500", spintext, "Video height is not saved")
+ self.assertIn("1000", spintext, "Video width is not saved")
+
+ def wait_for_file(self, path, time_out=20):
+ sleeped = 0
+ exists = False
+ while (sleeped <= time_out) and not exists:
+ sleeped += 2
+ sleep(2)
+ exists = os.path.exists(path)
+ return exists
+
+ def wait_for_update(self, path, timestamp, time_out=20):
+ sleeped = 0
+ new_timestamp = False
+ while (sleeped <= time_out) and new_timestamp == timestamp:
+ sleeped += 2
+ sleep(2)
+ new_timestamp = os.path.getmtime(path)
+ return new_timestamp != timestamp
+
+ def test_backup(self):
+ #Create empty project
+ sample = self.import_media()
+
+ #Save project
+ filename = "test_project%i.xptv" % time()
+ path = "/tmp/" + filename
+ backup_path = path + "~"
+ self.unlink.append(backup_path)
+ self.saveProject("/tmp/" + filename)
+
+ #Change somthing
+ seektime = self.search_by_text("0:00:00.000", self.pitivi, roleName="text")
+ self.assertIsNotNone(seektime)
+ self.insert_clip(sample)
+ self.nextb = self.pitivi.child(name="Next", roleName="push button")
+ self.nextb.click()
+ self.assertEqual(seektime.text, "0:00:01.227")
+
+ #It should save after 10 seconds if no changes made
+ self.assertTrue(self.wait_for_file(backup_path), "Backup not created")
+ self.assertTrue(os.path.getmtime(backup_path) -
+ os.path.getmtime(path) > 0,
+ "Backup is older than saved file")
+
+ #Try to quit, it should warn us
+ self.menubar.menu("Project").click()
+ self.menubar.menu("Project").menuItem("Quit").click()
+
+ #If finds button, means it warned
+ self.pitivi.child("Cancel").click()
+ self.saveProject(url=None, saveAs=False)
+ #Backup should be deleted, and no warning displayed
+ self.menubar.menu("Project").click()
+ self.menubar.menu("Project").menuItem("Quit").click()
+ self.assertFalse(os.path.exists(backup_path))
+ #Test if backup is found
+ self.setUp()
+ self.pitivi.child(name=filename).doubleClick()
+ sample = self.import_media("flat_colour1_640x480.png")
+ self.assertTrue(self.wait_for_file(backup_path, 120), "Backup not created")
+ self.tearDown(clean=False)
+ self.setUp()
+ self.pitivi.child(name=filename).doubleClick()
+ #Try restoring from backup
+ self.pitivi.child(name="Restore from backup").click()
+ samples = self.pitivi.tab("Media Library").findChildren(GenericPredicate(roleName="icon"))
+ self.assertEqual(len(samples), 2)
+ self.menubar.menu("Project").click()
+ self.assertFalse(self.menubar.menu("Project").menuItem("Save").sensitive)
+ #Behaved as saveAs
+
+ #Kill once more
+ self.tearDown(clean=False)
+ timestamp = os.path.getmtime(backup_path)
+ self.setUp()
+ self.pitivi.child(name=filename).doubleClick()
+ self.pitivi.child(name="Ignore backup").click()
+ #Backup is not deleted, not changed
+ self.assertEqual(timestamp, os.path.getmtime(backup_path))
+
+ #Look if backup updated, even it is newer than saved project
+
+ sample = self.import_media("flat_colour2_640x480.png")
+ self.assertTrue(self.wait_for_update(backup_path, timestamp))
+ #Try to quit, it should warn us (still newer version)
+ self.menubar.menu("Project").click()
+ self.menubar.menu("Project").menuItem("Quit").click()
+
+ #If finds button, means it warned
+ self.pitivi.child("Cancel").click()
+ self.saveProject(url=None, saveAs=False)
+
+ #Backup should be deleted, and no warning displayed
+ self.menubar.menu("Project").click()
+ self.menubar.menu("Project").menuItem("Quit").click()
+ self.assertFalse(os.path.exists(backup_path))
+
+ def test_load_save(self):
+ self.nextb = self.pitivi.child(name="Next", roleName="push button")
+ tab = self.pitivi.tab("Media Library")
+ seektime = self.search_by_text("0:00:00.000", self.pitivi, roleName="text")
+ infobar_media = tab.child(name="Add media to your project by dragging files and folders here or by using the \"Import Files...\" button.")
+ filename1 = "/tmp/test_project%i.xptv" % time()
+ filename2 = "/tmp/test_project%i.xptv" % time()
+
+ #Create project
+ self.assertTrue(infobar_media.showing)
+ sample = self.import_media()
+ self.insert_clip(sample)
+ self.saveProject(filename1)
+ self.assertFalse(infobar_media.showing)
+
+ #Create new, check if cleaned
+ sleep(0.5)
+ self.menubar.menu("Project").click()
+ self.menubar.menu("Project").menuItem("New").click()
+ self.pitivi.child(name="OK", roleName="push button").click()
+
+ icons = tab.findChildren(GenericPredicate(roleName="icon"))
+ self.nextb.click()
+ self.assertEqual(len(icons), 0)
+ self.assertEqual(seektime.text, "0:00:00.000")
+ self.assertTrue(infobar_media.showing)
+
+ #Create bigger project
+ sample = self.import_media()
+ self.import_media("flat_colour1_640x480.png")
+ self.insert_clip(sample, 2)
+ self.saveProject(filename2)
+ self.assertFalse(infobar_media.showing)
+
+ #Load first, check if populated
+ self.load_project(filename1)
+ icons = tab.findChildren(GenericPredicate(roleName="icon"))
+ self.nextb.click()
+ self.assertEqual(len(icons), 1)
+ self.assertEqual(seektime.text, "0:00:01.227")
+ self.assertFalse(infobar_media.showing)
+
+ #Load second, check if populated
+ self.load_project(filename2)
+ icons = tab.findChildren(GenericPredicate(roleName="icon"))
+ self.nextb.click()
+ self.assertEqual(len(icons), 2)
+ self.assertEqual(seektime.text, "0:00:02.455")
+ self.assertFalse(infobar_media.showing)
diff --git a/tests/dogtail_scripts/test_timeline.py b/tests/dogtail_scripts/test_timeline.py
new file mode 100644
index 0000000..0053a4a
--- /dev/null
+++ b/tests/dogtail_scripts/test_timeline.py
@@ -0,0 +1,235 @@
+#!/usr/bin/env python
+from test_help_func import HelpFunc
+from dogtail.predicate import GenericPredicate
+from helper_functions import improved_drag
+import dogtail.rawinput
+from time import sleep
+from pyatspi import Registry as registry
+from pyatspi import (KEY_SYM, KEY_PRESS, KEY_PRESSRELEASE, KEY_RELEASE)
+
+
+class TimelineTest(HelpFunc):
+ def setUp(self):
+ super(TimelineTest, self).setUp()
+ self.nextb = self.pitivi.child(name="Next", roleName="push button")
+
+ def help_test_insertEnd(self):
+ sample = self.import_media()
+ #Right click
+ seektime = self.search_by_text("0:00:00.000", self.pitivi, roleName="text")
+
+ self.assertIsNotNone(seektime)
+
+ sample.click(3)
+ buttons = self.pitivi.findChildren(
+ GenericPredicate(name="Insert at End of Timeline"))
+ buttons[1].click()
+ self.nextb.click()
+ self.assertEqual(seektime.text, "0:00:01.227")
+
+ #Add one more
+ sample.click(3)
+ buttons = self.pitivi.findChildren(
+ GenericPredicate(name="Insert at End of Timeline"))
+ buttons[1].click()
+ self.nextb.click()
+
+ self.assertEqual(seektime.text, "0:00:02.455")
+
+ def help_test_insertEndFast(self):
+ sample = self.import_media()
+ self.insert_clip(sample, 2)
+ self.nextb.click()
+
+ def test_drag_clip(self):
+ sample = self.import_media()
+ seektime = self.search_by_text("0:00:00.000", self.pitivi, roleName="text")
+ self.assertIsNotNone(seektime)
+
+ timeline = self.get_timeline()
+
+ center = lambda obj: (obj.position[0] + obj.size[0] / 2, obj.position[1] + obj.size[1] / 2)
+ improved_drag(center(sample), center(timeline))
+ self.nextb.click()
+ self.assertNotEqual(seektime.text, "0:00:00.000")
+
+ def test_multiple_drag(self):
+ sample = self.import_media()
+ seektime = self.search_by_text("0:00:00.000", self.pitivi, roleName="text")
+ timeline = self.get_timeline()
+ self.assertIsNotNone(seektime)
+ oldseek = seektime.text
+ center = lambda obj: (obj.position[0] + obj.size[0] / 2, obj.position[1] + obj.size[1] / 2)
+ endpos = []
+ endpos.append((timeline.position[0] + timeline.size[0] - 30, timeline.position[1] + 30))
+ endpos.append((timeline.position[0] + timeline.size[0] - 30, timeline.position[1] + 120))
+ endpos.append((timeline.position[0] + timeline.size[0] - 30, timeline.position[1] + 80))
+ for i in range(20):
+ if (i % 4 == 0):
+ #Drag to center, next layer, out, and then back in
+ improved_drag(center(sample), endpos[i % 3], middle=[center(timeline), endpos[(i + 1) % 2], center(sample)])
+ else:
+ #Simple drag
+ improved_drag(center(sample), endpos[i % 3])
+ #Give time to insert object
+ sleep(0.5)
+ self.nextb.click()
+ self.assertNotEqual(oldseek, seektime.text)
+ oldseek = seektime.text
+
+ def test_split(self):
+ self.help_test_insertEnd()
+ seektime = self.search_by_text("0:00:02.455", self.pitivi, roleName="text")
+ timeline = self.get_timeline()
+ #Adjust to different screen sizes
+ adj = (float)(timeline.size[0]) / 883
+
+ dogtail.rawinput.click(timeline.position[0] + 500 * adj, timeline.position[1] + 50)
+ self.pitivi.child(name="Split", roleName="push button").click()
+ dogtail.rawinput.click(timeline.position[0] + 450 * adj, timeline.position[1] + 50)
+ self.pitivi.child(name="Delete", roleName="push button").click()
+
+ self.nextb.click()
+ self.assertEqual(seektime.text, "0:00:02.455")
+
+ dogtail.rawinput.click(timeline.position[0] + 550 * adj, timeline.position[1] + 50)
+ dogtail.rawinput.pressKey("Del")
+ #self.pitivi.child(name="Delete", roleName="push button").click()
+
+ self.nextb.click()
+ self.assertEqual(seektime.text, "0:00:01.227")
+
+ def test_multiple_split(self):
+ self.help_test_insertEndFast()
+ seektime = self.search_by_text("0:00:02.455", self.pitivi, roleName="text")
+ timeline = self.get_timeline()
+ #Adjust to different screen sizes
+ adj = (float)(timeline.size[0]) / 883
+ tpos = timeline.position
+ pos = [50, 480, 170, 240, 350, 610, 410, 510]
+ #Sleeps needed for atspi
+ for k in pos:
+ for p in pos:
+ dogtail.rawinput.click(tpos[0] + (p + k / 10) * adj, tpos[1] + 50)
+ sleep(0.1)
+ dogtail.rawinput.pressKey("s")
+ #Just search some object to look if it still alive
+ self.pitivi.child(roleName="icon")
+
+ def test_transition(self):
+ self.help_test_insertEndFast()
+ seektime = self.search_by_text("0:00:02.455", self.pitivi, roleName="text")
+ timeline = self.get_timeline()
+ tpos = timeline.position
+
+ #Adjust to different screen sizes
+ adj = (float)(timeline.size[0]) / 883
+
+ dogtail.rawinput.press(tpos[0] + 500 * adj, tpos[1] + 50)
+ #Drag in, drag out, drag in and release
+ dogtail.rawinput.relativeMotion(-200 * adj, 10)
+ sleep(1)
+ dogtail.rawinput.relativeMotion(300 * adj, -10)
+ sleep(1)
+ dogtail.rawinput.absoluteMotion(tpos[0] + 300 * adj, tpos[1] + 50)
+ sleep(1)
+ dogtail.rawinput.release(tpos[0] + 300 * adj, tpos[1] + 50)
+ sleep(1)
+ dogtail.rawinput.click(tpos[0] + 250 * adj, tpos[1] + 50)
+ #Check if we selected transition
+ transitions = self.pitivi.child(name="Transitions", roleName="page tab")
+ iconlist = transitions.child(roleName="layered pane")
+ self.assertTrue(iconlist.sensitive)
+ iconlist.children[-2].select()
+ self.assertTrue(transitions.child(roleName="slider").sensitive)
+ transitions.child(roleName="slider").value = 50
+
+ def search_clip_end(self, y, seek, timeline):
+ minx = timeline.position[0] + 10.
+ maxx = timeline.position[0] + timeline.size[0] - 10.
+ minx = (minx + maxx) / 2
+ y += timeline.position[1]
+ dogtail.rawinput.click(maxx, y)
+ maxseek = seek.text
+ print maxseek
+ while maxx - minx > 2:
+ middle = (maxx + minx) / 2
+ dogtail.rawinput.click(middle, y)
+ sleep(0.1)
+ if seek.text == maxseek:
+ maxx = middle
+ else:
+ minx = middle
+ #+5 due to handle size
+ return maxx - timeline.position[0] + 5
+
+ def test_riple_roll(self):
+ self.help_test_insertEndFast()
+ seektime = self.search_by_text("0:00:02.455", self.pitivi, roleName="text")
+ timeline = self.get_timeline()
+ tpos = timeline.position
+ end = self.search_clip_end(30, seektime, timeline)
+
+ dogtail.rawinput.absoluteMotion(tpos[0] + end / 2 - 2, tpos[1] + 30)
+ registry.generateKeyboardEvent(dogtail.rawinput.keyNameToKeyCode("Control_L"), None, KEY_PRESS)
+ dogtail.rawinput.press(tpos[0] + end / 2 - 2, tpos[1] + 30)
+ sleep(0.5)
+ dogtail.rawinput.absoluteMotion(tpos[0] + end / 2 - 100, tpos[1] + 30)
+ sleep(0.5)
+ dogtail.rawinput.release(tpos[0] + end / 2 - 100, tpos[1] + 30)
+ registry.generateKeyboardEvent(dogtail.rawinput.keyNameToKeyCode("Control_L"), None, KEY_RELEASE)
+ self.nextb.click()
+ self.assertNotEqual(seektime.text, "0:00:02.455", "Not ripled, but trimed")
+
+ #Regresion test of adding effect
+ #Add effect
+ tab = self.pitivi.tab("Effect Library")
+ tab.click()
+ conftab = self.pitivi.tab("Clip configuration")
+ conftab.click()
+ center = lambda obj: (obj.position[0] + obj.size[0] / 2, obj.position[1] + obj.size[1] / 2)
+ table = conftab.child(roleName="table")
+ icon = self.search_by_text("Agingtv ", tab, roleName="icon")
+ improved_drag(center(icon), center(table))
+ self.nextb.click()
+ seekbefore = seektime.text
+ #Try riple and roll
+ dogtail.rawinput.absoluteMotion(tpos[0] + end / 2 - 102, tpos[1] + 30)
+ registry.generateKeyboardEvent(dogtail.rawinput.keyNameToKeyCode("Control_L"), None, KEY_PRESS)
+ dogtail.rawinput.press(tpos[0] + end / 2 - 102, tpos[1] + 30)
+ sleep(0.5)
+ dogtail.rawinput.absoluteMotion(tpos[0] + end / 2 - 200, tpos[1] + 30)
+ sleep(0.5)
+ dogtail.rawinput.release(tpos[0] + end / 2 - 200, tpos[1] + 30)
+ registry.generateKeyboardEvent(dogtail.rawinput.keyNameToKeyCode("Control_L"), None, KEY_RELEASE)
+ self.nextb.click()
+ self.assertNotEqual(seektime.text, seekbefore, "Not ripled affter adding effect")
+
+ def test_image_video_mix(self):
+ files = ["1sec_simpsons_trailer.mp4", "flat_colour2_640x480.png",
+ "flat_colour4_1600x1200.jpg", "flat_colour1_640x480.png",
+ "flat_colour3_320x180.png", "flat_colour5_1600x1200.jpg"]
+ samples = self.import_media_multiple(files)
+ seektime = self.search_by_text("0:00:00.000", self.pitivi, roleName="text")
+ timeline = self.get_timeline()
+ tpos = timeline.position
+
+ #One video, one image
+ for sample in samples[1:]:
+ self.insert_clip(sample)
+ self.insert_clip(samples[0])
+
+ end = self.search_clip_end(30, seektime, timeline)
+ cend = end / 11.139
+ dogtail.rawinput.absoluteMotion(tpos[0] + cend - 2, tpos[1] + 30)
+ registry.generateKeyboardEvent(dogtail.rawinput.keyNameToKeyCode("Shift_L"), None, KEY_PRESS)
+ dogtail.rawinput.press(tpos[0] + cend - 2, tpos[1] + 30)
+ sleep(0.5)
+ dogtail.rawinput.absoluteMotion(tpos[0] + cend - 40, tpos[1] + 30)
+ sleep(0.5)
+ dogtail.rawinput.release(tpos[0] + cend - 40, tpos[1] + 30)
+ registry.generateKeyboardEvent(dogtail.rawinput.keyNameToKeyCode("Shift_L"), None, KEY_RELEASE)
+ self.nextb.click()
+ self.assertNotEqual(seektime.text, "0:00:11.139")
+
+ #TODO: do something more with clips
diff --git a/tests/samples/1sec_simpsons_trailer.mp4 b/tests/samples/1sec_simpsons_trailer.mp4
new file mode 100644
index 0000000..640a27d
Binary files /dev/null and b/tests/samples/1sec_simpsons_trailer.mp4 differ
diff --git a/tests/samples/flat_colour4_1600x1200.jpg b/tests/samples/flat_colour4_1600x1200.jpg
new file mode 100644
index 0000000..80499d4
Binary files /dev/null and b/tests/samples/flat_colour4_1600x1200.jpg differ
diff --git a/tests/samples/flat_colour5_1600x1200.jpg b/tests/samples/flat_colour5_1600x1200.jpg
new file mode 100644
index 0000000..ccab6c5
Binary files /dev/null and b/tests/samples/flat_colour5_1600x1200.jpg differ
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]