~adam-disc0tech/ubuntu-autopilot-tests/fileroller

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
from autopilot.testcase import AutopilotTestCase
from autopilot.matchers import Eventually
from testtools.matchers import Equals, Contains
from testtools.matchers import NotEquals, DirExists, FileExists
from autopilot.input import Mouse, Pointer
from time import sleep
import logging
import os
try:
    from unittest import mock
except ImportError:
    import mock
import shutil
import tempfile

logger = logging.getLogger('__name__')


class FileRollerTests(AutopilotTestCase):
    '''Collection of autopilot test for file-roller (Archive Manager) '''

    def setUp(self):
        '''Set-up method'''
        super(FileRollerTests, self).setUp()
        #mock out the home dir
        self.home_dir = self._patch_home()

        #launch the app
        self.app = self.launch_test_application('file-roller')

        # only instantiate these once for multiple tests
        # these can only be instantiated here if you do not need to reload the
        # application during a test
        # As the Gtk ids change when application is relaunched and throws error
        # So for tests that are reloaded also grab
        # new Gtkobject id's after relaunch
        self.pointing_device = Pointer(Mouse.create())
        self.archiveWindow = self.app.select_single('FrWindow')
        self.add_files_button = self.app.select_single('GtkLabel',
                                                       label=u'Add Files')
        self.extract_button = self.app.select_single('GtkLabel',
                                                     label=u'Extract')
        self.open_button = self.app.select_single('GtkLabel', label=u'Open')
        self.new_archive_button = self.app.select_single('GtkToolButton',
                                                         name=u'New')

        #create symbolic link for fast test content location
        src_dir = '/usr/share/example-content/Ubuntu_Free_Culture_Showcase/'
        files = os.listdir(src_dir)
        for f in files:
            shutil.copyfile(src_dir + str(f), os.getenv("HOME") + '/' + str(f))

    def test_create_archive(self):
        '''Creates an archive and adds sample data,
           Window title must contain archive name'''

        tempArchive = _tempArchiveName()
        #Test: Archive must be created with sample data
        self.create_archive_with_sample_data(tempArchive)
        # If create archive successfull, then check here that the window title
        # is the name of the archive.
        (dirName, fileName) = os.path.split(tempArchive)
        self.assertThat(self.archiveWindow.title,
                        Eventually(Contains(fileName)))

        #Cleanup
        self.delete_temp_archive()

    def test_open_archive(self):
        '''Open archive window title must contains the archive name '''

        tempArchive = _tempArchiveName()
        # Call create and relaunch to get
        # a safe way of reloading an application
        self.create_and_relaunch(tempArchive)

        #Test: Must open archive
        self.open_test_archive(tempArchive)
        # if open archive successful, then check here that the window title
        # is the name of the archive.
        (dirName, fileName) = os.path.split(tempArchive)
        self.assertThat(self.archiveWindow.title,
                        Eventually(Contains(fileName)))
        # Cleanup
        self.delete_temp_archive()

    def test_extract_archive(self):
        '''Open archive and extract file'contents,'''

        tempArchive = _tempArchiveName()
        # Call create and relaunch to get
        # a safe way of reloading an application
        self.create_and_relaunch(tempArchive)
        self.assertThat(self.archiveWindow.title,
                        Eventually(Contains('Archive Manager')))
        #Test: Open and extract an archive
        self.extract_test_archive(tempArchive)
        ## assert we have come back to main window after extraction
        ## Test Will not get back to mainWindow if extraction failed.
        ## Check window title is same as archive
        (dirName, fileName) = os.path.split(tempArchive)
        self.assertThat(self.archiveWindow.title,
                        Eventually(Contains(fileName)))
        #Cleanup
        self.delete_temp_archive()
        self.delete_temp_directory(fileName)

    # this method needs some more assertions.
    # At the moment its relying that commands are correct
    def create_archive_with_sample_data(self, tempArchive):
        ''' Must create archive and add sample data'''
        #Click on the new archive button
        self.pointing_device.move_to_object(self.new_archive_button)
        self.pointing_device.click()
        # The new archive dialog window title must have 'New Archive'
        self.new_dialog = self.app.select_single('FrNewArchiveDialog')
        self.assertThat(self.new_dialog.title,
                        Eventually(Equals(u'New Archive')))

        #Enter name of new archive
        self.keyboard.type(tempArchive)

        # TODO: Figure out a gzip commpress, does not have an active Id enabled
        # select the create button and check it is clickable
        self.create_button = self.app.select_single('GtkButton',
                                                    label=u'create-archive')
        self.assertThat(self.create_button.label, Eventually(NotEquals(None)))
        # Click on Create button
        self.pointing_device.move_to_object(self.create_button)
        self.pointing_device.click()
        # Click on the add files button
        self.pointing_device.move_to_object(self.add_files_button)
        self.pointing_device.click()
        # The add files dialog title must contain 'Add Files'
        self.add_files_dialog = self.app.select_single('FrFileSelectorDialog')
        self.assertThat(self.add_files_dialog.title,
                        Eventually(Equals('Add Files')))
        # This is a horrible hacky workaround to add sample
        # files from /usr/share/example-content/*
        # Need to find a better workaround :S Location GtkEntry
        # doesnt work when entering file path
        # Maybe add some assertions to check that the
        # Location GTKEntry contains correct path
        #first ensure we are in the home directory

        self.keyboard.press_and_release("Alt+l")
        self.keyboard.press_and_release("Tab")
        self.keyboard.press_and_release("Tab")
        self.keyboard.press_and_release("Tab")

        self.keyboard.press_and_release("Space")
        self.keyboard.press_and_release("Down")
        self.keyboard.press_and_release("Down")
        self.keyboard.press_and_release("Space")

        # We must be able to click the '_Add' button
        self.add_folder_button = self.app.select_single('GtkLabel',
                                                        label=u'_Add')
        self.assertThat(self.add_folder_button.label,
                        Eventually(NotEquals(None)))
        #Click the '_Add" button
        self.pointing_device.move_to_object(self.add_folder_button)
        self.pointing_device.click()
        # sleep needed to give sample data enough time to be added
        sleep(10)

    # Method for opening an archive, needs assertions adding
    def open_test_archive(self, tempArchive):
        '''Open the test archive'''
        self.open_button = self.app.select_single('GtkLabel', label=u'Open')
        self.pointing_device.move_to_object(self.open_button)
        self.pointing_device.click()

        self.keyboard.press_and_release("Alt+l")
        self.keyboard.type(tempArchive)

        self.open_archive_button = self.app.select_single(
            'GtkLabel', label=u'_Open')
        self.pointing_device.move_to_object(self.open_archive_button)
        self.pointing_device.click()

    def extract_test_archive(self, tempArchive):
        '''Open Archive and extract the sample data'''

        self.open_test_archive(tempArchive)
        (dirName, fileName) = os.path.split(tempArchive)

        self.assertThat(self.archiveWindow.title,
                        Eventually(Contains(fileName)))

        # Check that the Extract button is now clickable
        self.assertThat(self.extract_button.label, Eventually(NotEquals(None)))

        #click on extract button
        self.pointing_device.move_to_object(self.extract_button)
        self.pointing_device.click()

        self.keyboard.press_and_release("Alt+l")
        self.keyboard.type(tempArchive)
        self.keyboard.press_and_release('Enter')

        self.extract_archive_button = self.app.select_single(
            'GtkLabel', label=u'_Extract')
        self.assertThat(self.extract_archive_button.label,
                        Eventually(NotEquals(None)))

        self.pointing_device.move_to_object(self.extract_archive_button)
        self.pointing_device.click()
        # need this sleep to give enough time for the GtkDialog time to load
        # before we can select it
        sleep(10)
        self.extract_dialog = self.app.select_single('GtkDialog')
        self.assertThat(self.extract_dialog.title,
                        Eventually(Contains(u"")))
        self.show_files_button = self.app.select_single(
            'GtkLabel', label=u'_Show the Files')
        self.assertThat(self.show_files_button.label,
                        Eventually(NotEquals(None)))

        self.pointing_device.move_to_object(self.show_files_button)
        self.pointing_device.click()

        #check the files have actually been extracted
        self.assertThat(tempArchive, DirExists())
        self.assertThat(tempArchive + '/' + '/How fast.ogg', FileExists())
        self.assertThat(tempArchive + '/' + '/Josh Woodward - Swansong.ogg', FileExists())

        # This sleep is needed as we can't introspect
        # nautilus when it shows the files
        # TODO: Once nautilus can be introspected we need to lose this sleep
        # and confirm nautilus window title Eventually Contains fileName
        sleep(10)

        self.keyboard.press_and_release("Alt+F4")

    def create_and_relaunch(self, tempArchive):
        ''' This method calls create archive_with_sample_data
            then will close the application and relaunch it
            grabbing new Gtk object id's'''
        # Create archive and check window title
        self.create_archive_with_sample_data(tempArchive)
        (dirName, fileName) = os.path.split(tempArchive)

        self.assertThat(self.archiveWindow.title,
                        Eventually(Contains(fileName)))
        # Close the Application
        self.keyboard.press_and_release('Ctrl+w')
        # launch a new instance of fire-roller
        self.app = self.launch_test_application('file-roller')
        # We need to get the new object id's here as we have reloaded the
        # application and will throw an error unknown id if we don't :)
        self.archiveWindow = self.app.select_single('FrWindow')
        self.add_files_button = self.app.select_single(
            'GtkLabel', label=u'Add Files')
        self.extract_button = self.app.select_single(
            'GtkLabel', label=u'Extract')
        self.open_button = self.app.select_single(
            'GtkLabel', label=u'Open')
        self.new_archive_button = self.app.select_single(
            'GtkToolButton', name=u'New')

    def delete_temp_archive(self):
        # Cleanup
        temp = self.archiveWindow.title
        # Strip archive name of whitespace
        temp = temp.strip()
        path = os.path.join('/tmp/'+temp)
        self.addCleanup(os.unlink, path)

    def delete_temp_directory(self, fileName):
        #Delete the extracted directory
        extract_path = os.path.join('/tmp/' + fileName)
        self.addCleanup(shutil.rmtree, extract_path)

    def _save_home(self):
            logger.debug('Saving HOME')
            home_dir = os.environ['HOME']
            backup_list = ('Music', )  # '.cache/mediascanner')
            backup_path = [os.path.join(home_dir, i) for i in backup_list]
            backups = [(i, '%s.bak' % i) for i in backup_path if os.path.exists(i)]
            for b in backups:
                logger.debug('backing up %s to %s' % b)
                try:
                    shutil.rmtree(b[1])
                except:
                    pass
                shutil.move(b[0], b[1])
                #self.addCleanup(shutil.move(b[1], b[0]))
            return home_dir

    def _patch_home(self):
        #make a temp dir
        temp_dir = tempfile.mkdtemp()
        #delete it, and recreate it to the length
        #required so our patching the db works
        #require a length of 25
        shutil.rmtree(temp_dir)
        temp_dir = temp_dir.ljust(25, 'X')
        os.mkdir(temp_dir)
        logger.debug("Created fake home directory " + temp_dir)
        self.addCleanup(shutil.rmtree, temp_dir)
        #if the Xauthority file is in home directory
        #make sure we copy it to temp home, otherwise do nothing
        xauth = os.path.expanduser(os.path.join('~', '.Xauthority'))
        if os.path.isfile(xauth):
            logger.debug("Copying .Xauthority to fake home " + temp_dir)
            shutil.copyfile(
                os.path.expanduser(os.path.join('~', '.Xauthority')),
                os.path.join(temp_dir, '.Xauthority'))
        patcher = mock.patch.dict('os.environ', {'HOME': temp_dir})
        patcher.start()
        logger.debug("Patched home to fake home directory " + temp_dir)
        self.addCleanup(patcher.stop)
        return temp_dir


#hardcoded global archiveName
def _tempArchiveName():
    '''Temporary archive name for testing with.'''
    sFile = tempfile.NamedTemporaryFile()
    sFile.close()
    return sFile.name