Merge lp:~boiko/dialer-app/rtm-fix_call_hangup_and_test_multi_call into lp:dialer-app/rtm-14.09

Proposed by Gustavo Pichorim Boiko
Status: Merged
Approved by: Gustavo Pichorim Boiko
Approved revision: 267
Merged at revision: 267
Proposed branch: lp:~boiko/dialer-app/rtm-fix_call_hangup_and_test_multi_call
Merge into: lp:dialer-app/rtm-14.09
Diff against target: 560 lines (+305/-78)
8 files modified
src/qml/LiveCallPage/LiveCall.qml (+3/-2)
src/qml/LiveCallPage/MultiCallDisplay.qml (+3/-0)
tests/autopilot/dialer_app/__init__.py (+26/-1)
tests/autopilot/dialer_app/fixture_setup.py (+83/-0)
tests/autopilot/dialer_app/helpers.py (+39/-15)
tests/autopilot/dialer_app/tests/test_calls.py (+7/-33)
tests/autopilot/dialer_app/tests/test_logs.py (+7/-27)
tests/autopilot/dialer_app/tests/test_multi_calls.py (+137/-0)
To merge this branch: bzr merge lp:~boiko/dialer-app/rtm-fix_call_hangup_and_test_multi_call
Reviewer Review Type Date Requested Status
Gustavo Pichorim Boiko (community) Approve
Review via email: mp+256537@code.launchpad.net

Commit message

Make sure the correct call is finished when pressing the hangup button on a multi-call scenario.
Also add autopilot tests to avoid this happening in the future.

Description of the change

Make sure the correct call is finished when pressing the hangup button on a multi-call scenario.
Also add autopilot tests to avoid this happening in the future.

To post a comment you must log in.
Revision history for this message
Gustavo Pichorim Boiko (boiko) wrote :

Already reviewed for vivid, approving.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'src/qml/LiveCallPage/LiveCall.qml'
--- src/qml/LiveCallPage/LiveCall.qml 2015-02-16 20:51:04 +0000
+++ src/qml/LiveCallPage/LiveCall.qml 2015-04-16 16:26:21 +0000
@@ -105,7 +105,7 @@
105 } else {105 } else {
106 closeTimer.running = false;106 closeTimer.running = false;
107 statusLabel.text = "";107 statusLabel.text = "";
108 liveCall.call = callManager.foregroundCall;108 liveCall.call = Qt.binding(callManager.foregroundCall);
109 }109 }
110 }110 }
111111
@@ -464,6 +464,7 @@
464464
465 MultiCallDisplay {465 MultiCallDisplay {
466 id: multiCallArea466 id: multiCallArea
467 objectName: "multiCallDisplay"
467 calls: callManager.calls468 calls: callManager.calls
468 opacity: 0469 opacity: 0
469 anchors {470 anchors {
@@ -630,7 +631,7 @@
630 }631 }
631632
632 LiveCallKeypadButton {633 LiveCallKeypadButton {
633 objectName: "pauseStartButton"634 objectName: "callHoldButton"
634 iconSource: {635 iconSource: {
635 if (callManager.backgroundCall) {636 if (callManager.backgroundCall) {
636 return "swap"637 return "swap"
637638
=== modified file 'src/qml/LiveCallPage/MultiCallDisplay.qml'
--- src/qml/LiveCallPage/MultiCallDisplay.qml 2015-02-10 18:10:34 +0000
+++ src/qml/LiveCallPage/MultiCallDisplay.qml 2015-04-16 16:26:21 +0000
@@ -40,8 +40,11 @@
4040
41 Item {41 Item {
42 id: callDelegate42 id: callDelegate
43 objectName: "callDelegate"
43 property QtObject callEntry: modelData44 property QtObject callEntry: modelData
44 property bool isLast: index == (multiCallRepeater.count - 1)45 property bool isLast: index == (multiCallRepeater.count - 1)
46 property bool active: !callEntry.held
47 property string phoneNumber: callEntry.phoneNumber
4548
46 height: units.gu(10) + conferenceArea.height49 height: units.gu(10) + conferenceArea.height
47 anchors {50 anchors {
4851
=== modified file 'tests/autopilot/dialer_app/__init__.py'
--- tests/autopilot/dialer_app/__init__.py 2015-02-11 18:29:21 +0000
+++ tests/autopilot/dialer_app/__init__.py 2015-04-16 16:26:21 +0000
@@ -35,6 +35,7 @@
3535
36 def _click_button(self, button):36 def _click_button(self, button):
37 """Generic way to click a button"""37 """Generic way to click a button"""
38 self.visible.wait_for(True)
38 button.visible.wait_for(True)39 button.visible.wait_for(True)
39 self.pointing_device.click_object(button)40 self.pointing_device.click_object(button)
40 return button41 return button
@@ -50,11 +51,35 @@
50 """Return the hangup button"""51 """Return the hangup button"""
51 return self.wait_select_single(objectName='hangupButton')52 return self.wait_select_single(objectName='hangupButton')
5253
54 def _get_call_hold_button(self):
55 """Return the call holding button"""
56 return self.wait_select_single(objectName='callHoldButton')
57
58 def _get_swap_calls_button(self):
59 """Return the swap calls button"""
60 return self._get_call_hold_button()
61
62 def get_multi_call_display(self):
63 """Return the multi call display panel"""
64 return self.wait_select_single(objectName='multiCallDisplay')
65
66 def get_multi_call_item_for_number(self, number):
67 """Return the multi call display item for the given number"""
68 return self.wait_select_single(objectName='callDelegate',
69 phoneNumber=number)
70
53 def click_hangup_button(self):71 def click_hangup_button(self):
54 """Click and return the hangup page"""72 """Click and return the hangup page"""
55 self.visible.wait_for(True)
56 return self._click_button(self._get_hangup_button())73 return self._click_button(self._get_hangup_button())
5774
75 def click_call_hold_button(self):
76 """Click the call holding button"""
77 return self._click_button(self._get_call_hold_button())
78
79 def click_swap_calls_button(self):
80 """Click the swap calls button"""
81 return self._click_button(self._get_swap_calls_button())
82
5883
59class PageWithBottomEdge(MainView):84class PageWithBottomEdge(MainView):
6085
6186
=== modified file 'tests/autopilot/dialer_app/fixture_setup.py'
--- tests/autopilot/dialer_app/fixture_setup.py 2014-08-01 15:25:39 +0000
+++ tests/autopilot/dialer_app/fixture_setup.py 2015-04-16 16:26:21 +0000
@@ -19,6 +19,8 @@
1919
20import fixtures20import fixtures
21import subprocess21import subprocess
22import os
23import shutil
2224
2325
24class TestabilityEnvironment(fixtures.Fixture):26class TestabilityEnvironment(fixtures.Fixture):
@@ -48,3 +50,84 @@
48 'QT_LOAD_TESTABILITY'50 'QT_LOAD_TESTABILITY'
49 ]51 ]
50 )52 )
53
54
55class FillCustomHistory(fixtures.Fixture):
56
57 history_db = "history.sqlite"
58 data_sys = "/usr/lib/python3/dist-packages/dialer_app/data/"
59 data_local = "dialer_app/data/"
60 database_path = '/tmp/' + history_db
61
62 prefilled_history_local = os.path.join(data_local, history_db)
63 prefilled_history_system = os.path.join(data_sys, history_db)
64
65 def setUp(self):
66 super(FillCustomHistory, self).setUp()
67 self.addCleanup(self._clear_test_data)
68 self.addCleanup(self._kill_service_to_respawn)
69 self._clear_test_data()
70 self._prepare_history_data()
71 self._kill_service_to_respawn()
72 self._start_service_with_custom_data()
73
74 def _prepare_history_data(self):
75 if os.path.exists(self.prefilled_history_local):
76 shutil.copy(self.prefilled_history_local, self.database_path)
77 else:
78 shutil.copy(self.prefilled_history_system, self.database_path)
79
80 def _clear_test_data(self):
81 if os.path.exists(self.database_path):
82 os.remove(self.database_path)
83
84 def _kill_service_to_respawn(self):
85 subprocess.call(['pkill', 'history-daemon'])
86
87 def _start_service_with_custom_data(self):
88 os.environ['HISTORY_SQLITE_DBPATH'] = self.database_path
89 with open(os.devnull, 'w') as devnull:
90 subprocess.Popen(['history-daemon'], stderr=devnull)
91
92
93class UseEmptyHistory(FillCustomHistory):
94 database_path = ':memory:'
95
96 def setUp(self):
97 super(UseEmptyHistory, self).setUp()
98
99 def _prepare_history_data(self):
100 # just avoid doing anything
101 self.database_path = ':memory:'
102
103 def _clear_test_data(self):
104 # don't do anything
105 self.database_path = ''
106
107
108class UsePhonesimModem(fixtures.Fixture):
109
110 def setUp(self):
111 super().setUp()
112
113 # configure the cleanups
114 self.addCleanup(self._hangupLeftoverCalls)
115 self.addCleanup(self._restoreModems)
116
117 self._switchToPhonesim()
118
119 def _switchToPhonesim(self):
120 # make sure the modem is running on phonesim
121 subprocess.call(['mc-tool', 'update', 'ofono/ofono/account0',
122 'string:modem-objpath=/phonesim'])
123 subprocess.call(['mc-tool', 'reconnect', 'ofono/ofono/account0'])
124
125 def _hangupLeftoverCalls(self):
126 # ensure that there are no leftover calls in case of failed tests
127 subprocess.call(["/usr/share/ofono/scripts/hangup-all", "/phonesim"])
128
129 def _restoreModems(self):
130 # set the modem objpath in telepathy-ofono to the real modem
131 subprocess.call(['mc-tool', 'update', 'ofono/ofono/account0',
132 'string:modem-objpath=/ril_0'])
133 subprocess.call(['mc-tool', 'reconnect', 'ofono/ofono/account0'])
51134
=== modified file 'tests/autopilot/dialer_app/helpers.py'
--- tests/autopilot/dialer_app/helpers.py 2014-06-20 13:26:49 +0000
+++ tests/autopilot/dialer_app/helpers.py 2015-04-16 16:26:21 +0000
@@ -1,8 +1,8 @@
1# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*-1# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*-
2#2#
3# Copyright 2014 Canonical Ltd.3# Copyright 2014-2015 Canonical Ltd.
4# Author: Omer Akram <omer.akram@canonical.com>4# Authors: Omer Akram <omer.akram@canonical.com>
5#5# Gustavo Pichorim Boiko <gustavo.boiko@canonical.com>
6# This program is free software; you can redistribute it and/or modify6# This program is free software; you can redistribute it and/or modify
7# it under the terms of the GNU General Public License version 3, as published7# it under the terms of the GNU General Public License version 3, as published
8# by the Free Software Foundation.8# by the Free Software Foundation.
@@ -21,6 +21,9 @@
21import sys21import sys
22import time22import time
23import dbus23import dbus
24import tempfile
25import os
26import shutil
2427
2528
26def wait_for_incoming_call():29def wait_for_incoming_call():
@@ -32,7 +35,7 @@
32 ['/usr/share/ofono/scripts/list-calls'],35 ['/usr/share/ofono/scripts/list-calls'],
33 stderr=subprocess.PIPE,36 stderr=subprocess.PIPE,
34 universal_newlines=True)37 universal_newlines=True)
35 if 'State = incoming' in out:38 if 'State = incoming' in out or 'State = waiting' in out:
36 break39 break
37 timeout -= 140 timeout -= 1
38 time.sleep(0.5)41 time.sleep(0.5)
@@ -44,17 +47,38 @@
44 subprocess.call(['pkill', '-f', 'notify-osd'])47 subprocess.call(['pkill', '-f', 'notify-osd'])
4548
4649
47def invoke_incoming_call():50def invoke_incoming_call(caller):
48 """Invoke an incoming call for test purpose."""51 """Receive an incoming call from the given caller
49 # magic number 199 will cause a callback from 1234567; dialing 19952
50 # itself will fail, so quiesce the error53 :parameter caller: the phone number calling
51 bus = dbus.SystemBus()54 """
52 vcm = dbus.Interface(bus.get_object('org.ofono', '/phonesim'),55
53 'org.ofono.VoiceCallManager')56 # prepare and send a Qt GUI script to phonesim, over its private D-BUS
54 try:57 # set up by ofono-phonesim-autostart
55 vcm.Dial('199', 'default')58 script_dir = tempfile.mkdtemp(prefix="phonesim_script")
56 except dbus.DBusException:59 os.chmod(script_dir, 0o755)
57 pass60 with open(os.path.join(script_dir, "call.js"), "w") as f:
61 f.write("""tabCall.gbIncomingCall.leCaller.text = "%s";
62tabCall.gbIncomingCall.pbIncomingCall.click();
63""" % (caller))
64
65 with open("/run/lock/ofono-phonesim-dbus.address") as f:
66 phonesim_bus = f.read().strip()
67 bus = dbus.bus.BusConnection(phonesim_bus)
68 script_proxy = bus.get_object("org.ofono.phonesim", "/")
69 script_proxy.SetPath(script_dir)
70 script_proxy.Run("call.js")
71 shutil.rmtree(script_dir)
72
73
74def accept_incoming_call():
75 """Accept an existing incoming call"""
76 subprocess.check_call(
77 [
78 "dbus-send", "--session", "--print-reply",
79 "--dest=com.canonical.Approver", "/com/canonical/Approver",
80 "com.canonical.TelephonyServiceApprover.AcceptCall"
81 ], stdout=subprocess.PIPE)
5882
5983
60def get_phonesim():84def get_phonesim():
6185
=== modified file 'tests/autopilot/dialer_app/tests/test_calls.py'
--- tests/autopilot/dialer_app/tests/test_calls.py 2015-02-16 20:51:04 +0000
+++ tests/autopilot/dialer_app/tests/test_calls.py 2015-04-16 16:26:21 +0000
@@ -10,7 +10,6 @@
1010
11"""Tests for the Dialer App using ofono-phonesim"""11"""Tests for the Dialer App using ofono-phonesim"""
1212
13import subprocess
14import os13import os
15import time14import time
1615
@@ -20,6 +19,7 @@
2019
21from dialer_app.tests import DialerAppTestCase20from dialer_app.tests import DialerAppTestCase
22from dialer_app import helpers21from dialer_app import helpers
22from dialer_app import fixture_setup
2323
2424
25@skipUnless(helpers.is_phonesim_running(),25@skipUnless(helpers.is_phonesim_running(),
@@ -30,36 +30,15 @@
30 """Tests for simulated phone calls."""30 """Tests for simulated phone calls."""
3131
32 def setUp(self):32 def setUp(self):
33 # provide clean history33 empty_history = fixture_setup.UseEmptyHistory()
34 self.history = os.path.expanduser(34 self.useFixture(empty_history)
35 "~/.local/share/history-service/history.sqlite")35 phonesim_modem = fixture_setup.UsePhonesimModem()
36 if os.path.exists(self.history):36 self.useFixture(phonesim_modem)
37 subprocess.call(["pkill", "history-daemon"])
38 os.rename(self.history, self.history + ".orig")
39
40 # make sure the modem is running on phonesim
41 subprocess.call(['mc-tool', 'update', 'ofono/ofono/account0',
42 'string:modem-objpath=/phonesim'])
43 subprocess.call(['mc-tool', 'reconnect', 'ofono/ofono/account0'])
44
45 super().setUp()37 super().setUp()
4638
47 def tearDown(self):39 def tearDown(self):
48 super().tearDown()40 super().tearDown()
4941
50 # ensure that there are no leftover calls in case of failed tests
51 subprocess.call(["/usr/share/ofono/scripts/hangup-all", "/phonesim"])
52
53 # restore history
54 if os.path.exists(self.history + ".orig"):
55 subprocess.call(["pkill", "history-daemon"])
56 os.rename(self.history + ".orig", self.history)
57
58 # set the modem objpath in telepathy-ofono to the real modem
59 subprocess.call(['mc-tool', 'update', 'ofono/ofono/account0',
60 'string:modem-objpath=/ril_0'])
61 subprocess.call(['mc-tool', 'reconnect', 'ofono/ofono/account0'])
62
63 @property42 @property
64 def history_list(self):43 def history_list(self):
65 # because of the object tree, more than just one item is returned, but44 # because of the object tree, more than just one item is returned, but
@@ -143,19 +122,14 @@
143 def test_incoming(self):122 def test_incoming(self):
144 """Incoming call"""123 """Incoming call"""
145 number = "1234567"124 number = "1234567"
146 helpers.invoke_incoming_call()125 helpers.invoke_incoming_call(number)
147126
148 # wait for incoming call, accept; it would be nicer to fake-click the127 # wait for incoming call, accept; it would be nicer to fake-click the
149 # popup notification, but as this isn't generated by dialer-app it128 # popup notification, but as this isn't generated by dialer-app it
150 # isn't exposed to autopilot129 # isn't exposed to autopilot
151 helpers.wait_for_incoming_call()130 helpers.wait_for_incoming_call()
152 time.sleep(1) # let's hear the ringing sound for a second :-)131 time.sleep(1) # let's hear the ringing sound for a second :-)
153 subprocess.check_call(132 helpers.accept_incoming_call()
154 [
155 "dbus-send", "--session", "--print-reply",
156 "--dest=com.canonical.Approver", "/com/canonical/Approver",
157 "com.canonical.TelephonyServiceApprover.AcceptCall"
158 ], stdout=subprocess.PIPE)
159133
160 # call back is from that number134 # call back is from that number
161 self.assertThat(135 self.assertThat(
162136
=== modified file 'tests/autopilot/dialer_app/tests/test_logs.py'
--- tests/autopilot/dialer_app/tests/test_logs.py 2015-02-13 17:54:03 +0000
+++ tests/autopilot/dialer_app/tests/test_logs.py 2015-04-16 16:26:21 +0000
@@ -10,10 +10,6 @@
1010
11"""Tests for the Dialer App"""11"""Tests for the Dialer App"""
1212
13import os
14import shutil
15import subprocess
16
17from autopilot.platform import model13from autopilot.platform import model
18from autopilot.matchers import Eventually14from autopilot.matchers import Eventually
19from testtools import skipIf15from testtools import skipIf
@@ -33,35 +29,19 @@
33class TestCallLogs(DialerAppTestCase):29class TestCallLogs(DialerAppTestCase):
34 """Tests for the call log panel."""30 """Tests for the call log panel."""
3531
36 db_file = 'history.sqlite'
37 local_db_dir = 'dialer_app/data/'
38 system_db_dir = '/usr/lib/python3/dist-packages/dialer_app/data/'
39 temp_db_file = '/tmp/' + db_file
40
41 def setUp(self):32 def setUp(self):
42 if os.path.exists('../../src/dialer-app'):33 # set the fixtures before launching the app
43 database = self.local_db_dir + self.db_file
44 else:
45 database = self.system_db_dir + self.db_file
46
47 if os.path.exists(self.temp_db_file):
48 os.remove(self.temp_db_file)
49
50 shutil.copyfile(database, self.temp_db_file)
51
52 subprocess.call(['pkill', 'history-daemon'])
53 os.environ['HISTORY_SQLITE_DBPATH'] = self.temp_db_file
54 with open(os.devnull, 'w') as devnull:
55 subprocess.Popen(['history-daemon'], stderr=devnull)
56
57 super().setUp()
58 testability_environment = fixture_setup.TestabilityEnvironment()34 testability_environment = fixture_setup.TestabilityEnvironment()
59 self.useFixture(testability_environment)35 self.useFixture(testability_environment)
60 self.main_view.dialer_page.reveal_bottom_edge_page()36 fill_history = fixture_setup.FillCustomHistory()
61 self.addCleanup(subprocess.call, ['pkill', '-f', 'history-daemon'])37 self.useFixture(fill_history)
62 self.fake_url_dispatcher = url_dispatcher_fixtures.FakeURLDispatcher()38 self.fake_url_dispatcher = url_dispatcher_fixtures.FakeURLDispatcher()
63 self.useFixture(self.fake_url_dispatcher)39 self.useFixture(self.fake_url_dispatcher)
6440
41 # now launch the app
42 super().setUp()
43 self.main_view.dialer_page.reveal_bottom_edge_page()
44
65 def _get_main_view(self, proxy_object):45 def _get_main_view(self, proxy_object):
66 return proxy_object.wait_select_single('QQuickView')46 return proxy_object.wait_select_single('QQuickView')
6747
6848
=== added file 'tests/autopilot/dialer_app/tests/test_multi_calls.py'
--- tests/autopilot/dialer_app/tests/test_multi_calls.py 1970-01-01 00:00:00 +0000
+++ tests/autopilot/dialer_app/tests/test_multi_calls.py 2015-04-16 16:26:21 +0000
@@ -0,0 +1,137 @@
1# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*-
2# Copyright 2015 Canonical
3# Author: Gustavo Pichorim Boiko <gustavo.boiko@canonical.com>
4#
5# This file is part of dialer-app.
6#
7# dialer-app is free software: you can redistribute it and/or modify it
8# under the terms of the GNU General Public License version 3, as published
9# by the Free Software Foundation.
10
11"""Multiple calls tests for the Dialer App using ofono-phonesim"""
12
13import time
14
15from autopilot.matchers import Eventually
16from testtools.matchers import Equals
17from testtools import skipUnless
18
19from dialer_app.tests import DialerAppTestCase
20from dialer_app import helpers
21from dialer_app import fixture_setup
22
23
24@skipUnless(helpers.is_phonesim_running(),
25 "this test needs to run under with-ofono-phonesim")
26class TestMultiCalls(DialerAppTestCase):
27 """Tests for simulated phone calls."""
28
29 def setUp(self):
30 empty_history = fixture_setup.UseEmptyHistory()
31 self.useFixture(empty_history)
32 phonesim_modem = fixture_setup.UsePhonesimModem()
33 self.useFixture(phonesim_modem)
34 super().setUp()
35
36 def tearDown(self):
37 super().tearDown()
38
39 @property
40 def history_list(self):
41 # because of the object tree, more than just one item is returned, but
42 # all references point to the same item, so take the first
43 return self.app.select_many(objectName="historyList")[0]
44
45 def get_history_for_number(self, number):
46 # because of the bottom edge tree structure, multiple copies of the
47 # same item are returned, so just use the first one
48 return self.history_list.select_many(
49 "HistoryDelegate", phoneNumber=number)[0]
50
51 def place_calls(self, numbers):
52 for number in numbers:
53 helpers.invoke_incoming_call(number)
54 helpers.wait_for_incoming_call()
55 time.sleep(1)
56 helpers.accept_incoming_call()
57 time.sleep(1)
58
59 def test_multi_call_panel(self):
60 """Make sure the multi call panel is visible when two calls are
61 available"""
62 firstNumber = '11111111'
63 secondNumber = '22222222'
64
65 # place the calls
66 self.place_calls([firstNumber, secondNumber])
67
68 # now ensure that the multi-call panel is visible
69 multi_call = self.main_view.live_call_page.get_multi_call_display()
70 self.assertThat(multi_call.visible, Eventually(Equals(True)))
71
72 # hangup one call
73 self.main_view.live_call_page.click_hangup_button()
74 self.assertThat(multi_call.visible, Eventually(Equals(False)))
75
76 # and the other one
77 self.main_view.live_call_page.click_hangup_button()
78
79 def test_swap_calls(self):
80 """Check that pressing the swap calls button change the call status"""
81 firstNumber = '11111111'
82 secondNumber = '22222222'
83
84 # place the calls
85 self.place_calls([firstNumber, secondNumber])
86
87 live_call = self.main_view.live_call_page
88 firstCallItem = live_call.get_multi_call_item_for_number(firstNumber)
89 secondCallItem = live_call.get_multi_call_item_for_number(secondNumber)
90
91 # check the current status
92 self.assertThat(firstCallItem.active, Eventually(Equals(False)))
93 self.assertThat(secondCallItem.active, Eventually(Equals(True)))
94
95 # now swap the calls
96 live_call.click_swap_calls_button()
97
98 # and make sure the calls changed
99 self.assertThat(firstCallItem.active, Eventually(Equals(True)))
100 self.assertThat(secondCallItem.active, Eventually(Equals(False)))
101
102 # hangup the calls
103 self.main_view.live_call_page.click_hangup_button()
104 time.sleep(1)
105 self.main_view.live_call_page.click_hangup_button()
106
107 def test_swap_and_hangup(self):
108 """Check that after swapping calls and hanging up the correct call
109 stays active"""
110 firstNumber = '11111111'
111 secondNumber = '22222222'
112
113 # place the calls
114 self.place_calls([firstNumber, secondNumber])
115
116 # at this point the calls should be like this:
117 # - 11111111: held
118 # - 22222222: active
119 # swap the calls then
120 self.main_view.live_call_page.click_swap_calls_button()
121
122 # - 11111111: active
123 # - 22222222: held
124 self.assertThat(
125 self.main_view.live_call_page.caller,
126 Eventually(Equals(firstNumber)))
127
128 # hangup the active call
129 self.main_view.live_call_page.click_hangup_button()
130
131 # and check that the remaining call is the one that was held
132 self.assertThat(
133 self.main_view.live_call_page.caller,
134 Eventually(Equals(secondNumber)))
135
136 # and hangup the remaining call too
137 self.main_view.live_call_page.click_hangup_button()

Subscribers

People subscribed via source and target branches