├── .gitattributes
├── Info.plist
├── LICENSE
├── README.md
├── activity
├── activity.swift
├── appointmentActivity.swift
├── callActivity.swift
└── commentActivity.swift
├── address
└── address.swift
├── addressBook
├── addressBookList.swift
├── contact.swift
├── customer.swift
└── relatedContacts.swift
├── extensions
└── XCUIElement+TCEExt.swift
├── home
├── home.swift
└── siderBar.swift
├── lead
├── lead.swift
├── leadsFilter.swift
└── leadsList.swift
├── login
└── login.swift
├── opportunity
├── opportunitiesFilter.swift
├── opportunitiesList.swift
└── opportunity.swift
├── product
├── product.swift
├── productFilter.swift
└── productList.swift
├── profile
└── profile.swift
├── reports
├── outlook.swift
├── overview.swift
├── reportsList.swift
└── summary.swift
├── settings
└── settings.swift
├── story.swift
└── utilis
├── SnapshotHelper.swift
├── XCUIElement+ext.swift
└── utils.swift
/.gitattributes:
--------------------------------------------------------------------------------
1 | # Auto detect text files and perform LF normalization
2 | * text=auto
--------------------------------------------------------------------------------
/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | BNDL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | 1
23 |
24 |
25 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2017 luis lu
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # XCUITest-Library
2 | XCUITest-Library is an example project of page object in swift implementation for XCUITest. You can refer to it and then restruct your iOS test cases.
3 |
--------------------------------------------------------------------------------
/activity/activity.swift:
--------------------------------------------------------------------------------
1 | //
2 | // activity.swift
3 | // anwstream
4 | //
5 | // Created by Lu, Luis on 09/11/2016.
6 | //
7 | //
8 |
9 | import Foundation
10 | import XCTest
11 |
12 | class activity: NSObject{
13 |
14 | let app = utils().app
15 |
16 | //header
17 | var backBtnOnCreateView: XCUIElement {
18 | return app.navigationBars["Add Activity"].buttons.element(boundBy: 0)
19 | }
20 |
21 | var doneBtnOnCreateView: XCUIElement {
22 | return app.buttons["create_confirm_btn"]
23 | }
24 |
25 | var backBtnOnEditView: XCUIElement {
26 | return app.buttons["edit_cancel_btn"]
27 | }
28 |
29 | var doneBtnOnEditView: XCUIElement {
30 | return app.buttons["edit_confirm_btn"]
31 | }
32 |
33 | var currentType: XCUIElement {
34 | return app.tables.cells.containing(.staticText, identifier: "Type").staticTexts.element(boundBy: 1)
35 |
36 | }
37 |
38 | func switchType(_ type:String){
39 | currentType.tap()
40 | app.pickerWheels.element.adjust(toPickerWheelValue: type)
41 | app.toolbars.buttons.element.tap()
42 | }
43 |
44 | func typeDetails(_ comments: String){
45 | app.tables.element(boundBy: 0).swipeUp()
46 | let textView = app.tables.cells.containing(.staticText, identifier: "Details").textViews.element
47 | textView.clearAndEnterText(comments, tapType: "forceTap", vector: CGVector.init(dx: 0.9, dy: 0.9))
48 | utils().handleKeyboard("Done")
49 | }
50 |
51 | func verifyType(_ type: String) {
52 | XCTAssertTrue(type == currentType.label, "Current type \(type) is not correct")
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/activity/appointmentActivity.swift:
--------------------------------------------------------------------------------
1 | //
2 | // appointmentActivity.swift
3 | // anwstream
4 | //
5 | // Created by Lu, Luis on 09/11/2016.
6 | //
7 | //
8 |
9 | import Foundation
10 | import XCTest
11 |
12 | class appointmentActivity: activity{
13 |
14 | var subjectField: XCUIElement {
15 | return app.tables.cells.containing(.staticText, identifier: "Subject").textFields.element
16 | }
17 |
18 | var startDateSelector:XCUIElement{
19 | return app.tables.cells.containing(.staticText, identifier: "Start Date").staticTexts.element(boundBy: 1)
20 | }
21 |
22 | var endDatesSelector:XCUIElement{
23 | return app.tables.cells.containing(.staticText, identifier: "End Date").staticTexts.element(boundBy: 1)
24 | }
25 |
26 | var reminderMeSelector:XCUIElement{
27 | return app.tables.cells.containing(.staticText, identifier: "Remeber me").staticTexts.element(boundBy: 1)
28 | }
29 |
30 | var addAttendeeBtn:XCUIElement{
31 | return app.tables.buttons["Add Attendee"]
32 | }
33 |
34 | var confirmAddressBtn:XCUIElement{
35 | return app.buttons["confirm_address"]
36 | }
37 |
38 | var addLocationBtn:XCUIElement{
39 | return app.tables.buttons["Add Location"]
40 | }
41 |
42 | func typeSubject(_ subjectInfo:String){
43 | utils().swipeUp()
44 | subjectField.tap()
45 | subjectField.typeText(subjectInfo)
46 | utils().handleKeyboard("Done")
47 | }
48 |
49 | func selectReminderMe(_ reminderRule:String){
50 | reminderMeSelector.tap()
51 | app.pickerWheels.element.adjust(toPickerWheelValue: reminderRule)
52 | }
53 |
54 | func addAttendee(_ attendeeList:Array){
55 | addAttendeeBtn.tap()
56 | if (!app.textFields["anwSearchField"].exists) {
57 | addAttendeeBtn.tap()
58 | }
59 | for attendee in attendeeList{
60 | app.textFields["anwSearchField"].clearAndEnterText(attendee)
61 | app.tables.cells.containing(.staticText, identifier: attendee).element.forceTap()
62 | }
63 | addressBook().createBtn.tap()
64 | snapshot("addAttendeeScreen")
65 | verifyAttendeeDisplays(attendeeList)
66 | }
67 |
68 | func addLocation(_ locationInfo:String){
69 | app.tables.element.swipeUp()
70 | addLocationBtn.tap()
71 |
72 | if (!app.textFields["Enter the location"].exists) {
73 | addLocationBtn.tap()
74 | }
75 | app.textFields["Enter the location"].tap()
76 | app.textFields["Enter the location"].typeText(locationInfo)
77 | //utils().handleKeyboard("Done")
78 | confirmAddressBtn.tap()
79 | verifyLocationDisplays(locationInfo)
80 | }
81 |
82 | func add(_ subject:String, _ details:String, startDate:String?=nil, endDate:String?=nil, reminderMeRule:String?=nil, attendeeList:Array?=nil, location:String?=nil){
83 | self.switchType("Appointment")
84 | snapshot("addAppointmentActivityScreen1")
85 | typeSubject(subject)
86 | if startDate != nil {
87 | utils().handleDateTimePicker(startDateSelector, dateTime: startDate!)
88 | }
89 | if endDate != nil {
90 | utils().handleDateTimePicker(endDatesSelector,dateTime: endDate!)
91 | }
92 | if reminderMeRule != nil {
93 | selectReminderMe(reminderMeRule!)
94 | }
95 | if attendeeList != nil {
96 | utils().swipeDown()
97 | addAttendee(attendeeList!)
98 | }
99 | if let realLocation=location {
100 | addLocation(realLocation)
101 | }
102 | self.typeDetails(details)
103 | snapshot("addAppointmentActivityScreen2")
104 | self.doneBtnOnCreateView.tap()
105 | app.navigationBars.element.tap() // workaround to interact with the app again for the alert handler to fire
106 | }
107 |
108 | /**
109 | - parameter attendeeList: attendee list need verify in activity page
110 | */
111 | func verifyAttendeeDisplays(_ attendeeList:Array){
112 | for attendee in attendeeList{
113 | let attendeePartialValue = NSPredicate(format: "label CONTAINS[CD] %@",attendee)
114 | app.tables.staticTexts.matching(attendeePartialValue).element.verifyExists("Can't found expected \(attendee) attendee ");
115 | }
116 | }
117 |
118 | func verifyLocationDisplays(_ location:String){
119 | let locationPartialValue = NSPredicate(format: "label CONTAINS[CD] %@",location)
120 | app.tables.staticTexts.matching(locationPartialValue).element.verifyExists("Can't found expected \(location) location ")
121 | }
122 |
123 | }
124 |
--------------------------------------------------------------------------------
/activity/callActivity.swift:
--------------------------------------------------------------------------------
1 | //
2 | // callActivity.swift
3 | // anwstream
4 | //
5 | // Created by Lu, Luis on 09/11/2016.
6 | //
7 | //
8 |
9 | import Foundation
10 | import XCTest
11 |
12 | class callActivity: activity{
13 |
14 | var durationField: XCUIElement {
15 | return app.tables.cells.containing(.staticText, identifier: "Duration").textFields.element
16 | }
17 |
18 | var dateSelector: XCUIElement {
19 | return app.tables.cells.containing(.staticText, identifier: "Date").staticTexts.element(boundBy: 1)
20 | }
21 |
22 | func create(_ details:String, dateTime:String?=nil, durationTime:String="15"){
23 | self.switchType("Call")
24 | self.input(details, dateTime: dateTime, durationTime: durationTime)
25 | self.doneBtnOnCreateView.tap()
26 | }
27 |
28 | func verifyType() {
29 | self.verifyType("Call")
30 | }
31 |
32 | func edit(_ details:String, dateTime:String?=nil, durationTime:String="15") {
33 | self .input(details, dateTime: dateTime, durationTime: durationTime)
34 | self.doneBtnOnEditView.tap()
35 | }
36 |
37 | func input(_ details:String, dateTime:String?=nil, durationTime:String="15") {
38 | if dateTime != nil{
39 | utils().handleDateTimePicker(dateSelector, dateTime: dateTime!)
40 | }
41 | if durationTime != "15"{
42 | durationField.clearAndEnterText(durationTime)
43 | }
44 | self.typeDetails(details)
45 | snapshot("addCallActivityScreen")
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/activity/commentActivity.swift:
--------------------------------------------------------------------------------
1 | //
2 | // activity.swift
3 | // anwstream
4 | //
5 | // Created by Lu, Luis on 08/11/2016.
6 | //
7 | //
8 |
9 | import Foundation
10 | import XCTest
11 |
12 | class commentActivity: activity{
13 |
14 | var date: XCUIElement {
15 | return app.tables.cells.containing(.staticText, identifier: "Date").staticTexts.element(boundBy: 1)
16 | }
17 |
18 | func create(_ details:String, dateTime:String?=nil){
19 | self.input(details, dateTime: dateTime)
20 | self.doneBtnOnCreateView.tap()
21 | }
22 |
23 | func edit(_ details:String, dateTime:String?=nil){
24 | self.input(details, dateTime: dateTime)
25 | self.doneBtnOnEditView.tap()
26 | }
27 |
28 | func input(_ details:String, dateTime:String?=nil){
29 | if dateTime != nil{
30 | // utils().handleDateTimePicker(date, dateTime: dateTime!)
31 | }
32 | self.typeDetails(details)
33 | snapshot("commentActivityScreen")
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/address/address.swift:
--------------------------------------------------------------------------------
1 | //
2 | // address.swift
3 | // anwstream
4 | //
5 | //
6 | //
7 | //
8 |
9 | import Foundation
10 | import XCTest
11 |
12 | class address: NSObject {
13 | let app = utils().app
14 |
15 | var doneBtnOnCreateView : XCUIElement {
16 | return app.navigationBars["Add Address"].buttons.element(boundBy: 1)
17 | }
18 |
19 | var doneBtnOnEditView : XCUIElement {
20 | return app.buttons["edit_confirm_btn"]
21 | }
22 |
23 | var recipient : XCUIElement {
24 | return app.tables.cells.containing(.staticText, identifier: "Recipient").textFields.element
25 | }
26 |
27 | var street1 : XCUIElement {
28 | return app.tables.cells.containing(.staticText, identifier: "Street 1").textFields.element
29 | }
30 |
31 | var street2 : XCUIElement {
32 | return app.tables.cells.containing(.staticText, identifier: "Street 2").textFields.element
33 | }
34 |
35 | var city : XCUIElement {
36 | return app.tables.cells.containing(.staticText, identifier: "City").textFields.element
37 | }
38 |
39 | var state : XCUIElement {
40 | return app.tables.cells.containing(.staticText, identifier: "State/Province/Region").staticTexts.element(boundBy: 2)
41 | }
42 |
43 | var zipCode : XCUIElement {
44 | return app.tables.cells.containing(.staticText, identifier: "Zip Code").textFields.element
45 | }
46 |
47 | var country : XCUIElement {
48 | return app.tables.cells.containing(.staticText, identifier: "Country/Region").staticTexts.element(boundBy: 2)
49 | }
50 |
51 | var cellphone : XCUIElement {
52 | return app.tables.cells.containing(.staticText, identifier: "Cellphone").textFields.element
53 | }
54 |
55 | var telephone : XCUIElement {
56 | return app.tables.cells.containing(.staticText, identifier: "Telephone").textFields.element
57 | }
58 |
59 | var type : XCUIElement {
60 | return app.tables.cells.containing(.staticText, identifier: "Type").textFields.element
61 | }
62 |
63 | func createAddress(recipient: String?=nil, street1:String?=nil, street2:String?=nil, city:String?=nil, state:String?=nil, zipCode:String?=nil, country:String?=nil, cellphone:String?=nil, telephone:String?=nil, type:String?=nil) {
64 | self .inputAddress(recipient: recipient, street1: street1, street2: street2, city: city, state: state, zipCode: zipCode, country: country, cellphone: cellphone, telephone: telephone, type: type)
65 | self.doneBtnOnCreateView.tap()
66 | }
67 |
68 | func editAddress(recipient: String?=nil, street1:String?=nil, street2:String?=nil, city:String?=nil, state:String?=nil, zipCode:String?=nil, country:String?=nil, cellphone:String?=nil, telephone:String?=nil, type:String?=nil) {
69 | self .inputAddress(recipient: recipient, street1: street1, street2: street2, city: city, state: state, zipCode: zipCode, country: country, cellphone: cellphone, telephone: telephone, type: type)
70 | self.doneBtnOnEditView.tap()
71 | }
72 |
73 | func inputAddress(recipient: String?=nil, street1:String?=nil, street2:String?=nil, city:String?=nil, state:String?=nil, zipCode:String?=nil, country:String?=nil, cellphone:String?=nil, telephone:String?=nil, type:String?=nil) {
74 | if (recipient != nil) {
75 | self.recipient.inputText(recipient!)
76 | }
77 |
78 | if (street1 != nil) {
79 | self.street1.inputText(street1!)
80 | }
81 |
82 | if (street2 != nil) {
83 | self.street2.inputText(street2!)
84 | }
85 |
86 | if (city != nil) {
87 | self.city.inputText(city!)
88 | }
89 |
90 | if (country != nil) {
91 | self.country.tap()
92 | app.pickerWheels.element.adjust(toPickerWheelValue: country!)
93 | app.toolbars.buttons.element.tap()
94 | }
95 |
96 | if (state != nil) {
97 | self.state.tap()
98 | app.pickerWheels.element.adjust(toPickerWheelValue: state!)
99 | app.toolbars.buttons.element.tap()
100 | }
101 |
102 | if (zipCode != nil) {
103 | self.zipCode.inputText(zipCode!)
104 | }
105 |
106 | if (cellphone != nil) {
107 | self.cellphone.inputText(cellphone!)
108 | }
109 |
110 | if (telephone != nil) {
111 | self.telephone.inputText(telephone!)
112 | }
113 |
114 | if (type != nil) {
115 | utils().swipeUp()
116 | self.type.inputText(type!)
117 | }
118 | }
119 |
120 | func verifyDisplay (recipient: String?=nil, street1:String?=nil, street2:String?=nil, city:String?=nil, state:String?=nil, zipCode:String?=nil, country:String?=nil, cellphone:String?=nil, telephone:String?=nil, type:String?=nil) {
121 | if (recipient != nil) {
122 | self.recipient.verifyTextValue(value: recipient!)
123 | }
124 |
125 | if (street1 != nil) {
126 | self.street1.verifyTextValue(value: street1!)
127 | }
128 |
129 | if (street2 != nil) {
130 | self.street2.verifyTextValue(value: street2!)
131 | }
132 |
133 | if (city != nil) {
134 | self.city.verifyTextValue(value: city!)
135 | }
136 |
137 | if (state != nil) {
138 | self.state.verifyLabel(label: state!)
139 | }
140 |
141 | if (zipCode != nil) {
142 | self.zipCode.verifyTextValue(value: zipCode!)
143 | }
144 |
145 | if (country != nil) {
146 | self.country.verifyLabel(label: country!)
147 | }
148 |
149 | if (cellphone != nil) {
150 | self.cellphone.verifyTextValue(value: cellphone!)
151 | }
152 |
153 | if (telephone != nil) {
154 | self.telephone.verifyTextValue(value: telephone!)
155 | }
156 |
157 | if (type != nil) {
158 | self.type.verifyTextValue(value: type!)
159 | }
160 | }
161 | }
162 |
--------------------------------------------------------------------------------
/addressBook/addressBookList.swift:
--------------------------------------------------------------------------------
1 | //
2 | // addressBookList.swift
3 | // anwstream
4 | //
5 | // on 2/8/17.
6 | //
7 | //
8 |
9 | import Foundation
10 | import XCTest
11 |
12 | class addressBook : NSObject {
13 |
14 | static let ADDRESS_BOOK_LIST_NAME : String = "Address Book"
15 |
16 | let app = utils().app;
17 |
18 | var leftMenuBtn : XCUIElement {
19 | return app.navigationBars.element.buttons.element(boundBy: 0)
20 | }
21 |
22 | var createBtn : XCUIElement {
23 | return app.navigationBars.matching(identifier: addressBook.ADDRESS_BOOK_LIST_NAME).buttons.element(boundBy: 1)
24 | }
25 |
26 | var createCorporateBtn : XCUIElement {
27 | return self.btnWithText("Corporate")
28 | }
29 |
30 | var createIndividualBtn : XCUIElement {
31 | return self.btnWithText("Individual")
32 | }
33 |
34 | var createContactBtn : XCUIElement {
35 | return self.btnWithText("Contact")
36 | }
37 |
38 | var cancelBtn : XCUIElement {
39 | return self.btnWithText("Cancel")
40 | }
41 |
42 | var searchField : XCUIElement {
43 | return app.searchFields.element
44 | }
45 |
46 | func cellWithText(_ identifier: String) -> XCUIElement{
47 | return app.tables.cells.staticTexts[identifier]
48 | }
49 |
50 | func cellWithTextField(_ identifier: String) -> XCUIElement{
51 | return app.tables.cells.textFields[identifier]
52 | }
53 |
54 | func btnWithText(_ text: String) -> XCUIElement {
55 | return app.buttons[text]
56 | }
57 |
58 | func selectCell(_ identifier: String) {
59 | let cell = self.cellWithText(identifier)
60 | cell.tap()
61 | }
62 |
63 | func searchAndGoToDetail(_ identifier:String) {
64 | self.searchField.tap()
65 | self.searchField.typeText(identifier)
66 | utils().handleKeyboard("Search")
67 | self.cellWithText(identifier).tap()
68 | }
69 | }
70 |
--------------------------------------------------------------------------------
/addressBook/contact.swift:
--------------------------------------------------------------------------------
1 | //
2 | // contact.swift
3 | // anwstream
4 | //
5 | // on 2/9/17.
6 | //
7 | //
8 |
9 | import Foundation
10 | import XCTest
11 |
12 | class contact : NSObject {
13 | static let FIRST_NAME_LABEL : String = "First Name"
14 | static let LAST_NAME_LABEL : String = "Last Name"
15 | static let POSITION_LABEL : String = "Position"
16 | static let CELLPHONE_LABEL : String = "Cellphone"
17 | static let OFFICEPHONE_LABEL : String = "Phone"
18 | static let EMAIL_LABEL : String = "Email"
19 | static let STATUS_LABEL : String = "Status"
20 |
21 | let app = utils().app
22 |
23 | var leftMenuBtn : XCUIElement {
24 | return app.navigationBars.element.buttons.element(boundBy: 0)
25 | }
26 |
27 | var rightMenuBtn : XCUIElement {
28 | return app.navigationBars.matching(identifier: "Address Book").buttons.element(boundBy: 1)
29 | }
30 |
31 | var addAddressBtn : XCUIElement {
32 | return app.tables.buttons["Add Address"]
33 | }
34 |
35 | func cell(_ identifier: String, tableIdentifier:String? = nil) -> XCUIElement {
36 | let predicate = NSPredicate(format: "label CONTAINS[CD] %@",identifier)
37 | var table : XCUIElement;
38 | if (tableIdentifier == nil) {
39 | table = app.tables.element
40 | } else {
41 | table = app.tables[tableIdentifier!]
42 | }
43 | return table.staticTexts.matching(predicate).element
44 | }
45 |
46 | func btnWithText(_ text: String) -> XCUIElement{
47 | return app.buttons[text]
48 | }
49 |
50 | func swipeToAddAddress(){
51 | utils().swipeUpUntilElementVisible(element: contact().addAddressBtn)
52 | utils().swipeUp()
53 | }
54 | }
55 |
56 | class contactEdit: contact {
57 | var callBtn : XCUIElement {
58 | return self.btnWithText("Call")
59 | }
60 |
61 | var emailBtn : XCUIElement {
62 | return self.btnWithText("Email")
63 | }
64 |
65 | var locateBtn : XCUIElement {
66 | return self.btnWithText("Locate")
67 | }
68 |
69 | var contactInfoNavBtn : XCUIElement {
70 | return app.buttons["basicInfo-editBtn"]
71 | }
72 |
73 | var addActivityBtn : XCUIElement {
74 | return app.tables.buttons["Add Activity"]
75 | }
76 |
77 | var detailsNavBtn : XCUIElement {
78 | return app.otherElements["creationInfo"].buttons.element
79 | }
80 |
81 | var firstName : XCUIElement {
82 | return self.textWithLabel(contact.FIRST_NAME_LABEL)
83 | }
84 |
85 | var status : XCUIElement {
86 | return self.textWithLabel(contact.STATUS_LABEL)
87 | }
88 |
89 | var infoPickerCancelView : XCUIElement {
90 | return app.otherElements["infoPickerCancelView"]
91 | }
92 |
93 | func textWithLabel(_ label:String) -> XCUIElement {
94 | return app.tables.cells.containing(.staticText, identifier: label).staticTexts.element(boundBy: 1)
95 | }
96 |
97 | func verifyActivityDisplay(_ activityText:String) {
98 | let predicate = NSPredicate(format: "label CONTAINS[CD] %@",activityText)
99 | app.tables.staticTexts.matching(predicate).element.verifyExists("Can't found expected \(activityText) contact ")
100 | }
101 |
102 | func tapOnActivity(_ identifier: String) {
103 | app.tables.staticTexts[identifier].tap()
104 | }
105 |
106 | func editContactInformation(firstName:String?=nil, lastName:String?=nil, position:String?=nil, cellPhone:String?=nil, officePhone:String?=nil, email:String?=nil) {
107 | self.contactInfoNavBtn.tap()
108 |
109 | if ((firstName) != nil) {
110 | let field = app.tables.cells.containing(.staticText, identifier: contact.FIRST_NAME_LABEL).textFields.element
111 | field.tap()
112 | field.clearAndEnterText(firstName!)
113 | utils().handleKeyboard("Done")
114 | }
115 |
116 | if ((lastName) != nil) {
117 | let field = app.tables.cells.containing(.staticText, identifier: contact.LAST_NAME_LABEL).textFields.element
118 | field.tap()
119 | field.clearAndEnterText(lastName!)
120 | utils().handleKeyboard("Done")
121 | }
122 |
123 | if ((position) != nil) {
124 | // let field = app.tables.cells.containing(.staticText, identifier: "Last Name").textFields.element
125 | // field.tap()
126 | // field.typeText(lastName!)
127 | // utils().handleKeyboard("Done")
128 | }
129 |
130 | if ((cellPhone) != nil) {
131 | let field = app.tables.cells.containing(.staticText, identifier: contact.CELLPHONE_LABEL).textFields.element
132 | field.tap()
133 | field.clearAndEnterText(cellPhone!)
134 | utils().handleKeyboard("Done")
135 | }
136 |
137 | if ((officePhone) != nil) {
138 | let field = app.tables.cells.containing(.staticText, identifier: contact.OFFICEPHONE_LABEL).textFields.element
139 | field.tap()
140 | field.clearAndEnterText(officePhone!)
141 | utils().handleKeyboard("Done")
142 | }
143 |
144 | if ((email) != nil) {
145 | let field = app.tables.cells.containing(.staticText, identifier: contact.EMAIL_LABEL).textFields.element
146 | field.tap()
147 | field.clearAndEnterText(email!)
148 | utils().handleKeyboard("Done")
149 | }
150 |
151 | //save change
152 | app.buttons.element(boundBy: 1).tap()
153 | }
154 |
155 | func editStatus(_ status: String) {
156 | self.contactInfoNavBtn.tap()
157 |
158 | let statusSwitch = app.tables.cells.containing(.staticText, identifier: contact.STATUS_LABEL).staticTexts.element(boundBy: 1)
159 | statusSwitch.tap()
160 | app.pickerWheels.element.adjust(toPickerWheelValue: status)
161 | app.buttons["edit_confirm_btn"].tap()
162 |
163 | //save change
164 | app.buttons.element(boundBy: 1).tap()
165 | }
166 |
167 | func cellOnInfoPickerView(_ identifier: String) -> XCUIElement {
168 | return self.cell(identifier, tableIdentifier: "infoPickerTable")
169 | }
170 | }
171 |
172 | class contactCreate: contact {
173 |
174 | var lastName : XCUIElement {
175 | return self.textFieldWithLabel("Last Name")
176 | }
177 |
178 | override var rightMenuBtn : XCUIElement {
179 | return app.navigationBars.matching(identifier: "Add Contact").buttons.element(boundBy: 1)
180 | }
181 |
182 | func textFieldWithLabel(_ label:String) -> XCUIElement {
183 | return app.tables.cells.containing(.staticText, identifier: label).textFields.element
184 | }
185 |
186 | func selectCompany(_ identifier: String) {
187 | self.cell("Choose or add company").tap()
188 | addressBook().selectCell(identifier)
189 | }
190 |
191 | }
192 |
--------------------------------------------------------------------------------
/addressBook/customer.swift:
--------------------------------------------------------------------------------
1 | //
2 | // corporateCustomer.swift
3 | // anwstream
4 | //
5 | // on 2/9/17.
6 | //
7 | //
8 |
9 | import Foundation
10 | import XCTest
11 |
12 | class customer: NSObject {
13 | static let CORPORATE_NAME = "Corporate Name"
14 | static let OFFICE_PHONE = "Office Phone"
15 | static let EMAIL = "Email"
16 | static let WEBSITE = "Website"
17 | static let STATUS = "Status"
18 | static let FIRST_NAME = "First Name"
19 | static let LAST_NAME = "Last Name"
20 | static let POSITION = "Position"
21 | static let COMPANY = "Company"
22 | static let CELLPHONE = "Cellphone"
23 |
24 | let app = utils().app
25 |
26 | var leftMenuBtn: XCUIElement {
27 | return app.navigationBars.element.buttons.element(boundBy: 0)
28 | }
29 |
30 | var rightMenuBtn: XCUIElement {
31 | return app.navigationBars.element.buttons.element(boundBy: 1)
32 | }
33 |
34 | var addAddressBtn : XCUIElement {
35 | return app.tables.buttons["Add Address"]
36 | }
37 |
38 | var status: XCUIElement {
39 | return app.tables.cells.containing(.staticText, identifier: customer.STATUS).staticTexts.element(boundBy: 1)
40 | }
41 |
42 | func cell(_ identifier: String, tableIdentifier:String? = nil) -> XCUIElement {
43 | let predicate = NSPredicate(format: "label CONTAINS[CD] %@",identifier)
44 | var table : XCUIElement;
45 | if (tableIdentifier == nil) {
46 | table = app.tables.element
47 | } else {
48 | table = app.tables[tableIdentifier!]
49 | }
50 | return table.staticTexts.matching(predicate).element(boundBy: 0)
51 | }
52 |
53 | func textWithLabel(_ label:String) -> XCUIElement {
54 | return app.tables.cells.containing(.staticText, identifier: label).staticTexts.element(boundBy: 1)
55 | }
56 |
57 | func deleteCell(_ identifier:String) {
58 | self.cell(identifier).swipeLeft()
59 | snapshot("deleteCell")
60 | app.tables.cells.containing(.staticText, identifier: identifier).buttons["Delete"].tap()
61 | }
62 |
63 | func textFieldWithLabel(_ label:String) -> XCUIElement {
64 | return app.tables.cells.containing(.staticText, identifier: label).textFields.element
65 | }
66 |
67 | func swipeToActivity(){
68 | utils().swipeUpUntilElementVisible(element: customerEdit().addActivityBtn)
69 | utils().swipeUp()
70 | }
71 |
72 | func swipeToAddress(){
73 | utils().swipeUpUntilElementVisible(element: customerEdit().addAddressBtn)
74 | utils().swipeUp()
75 | }
76 | }
77 |
78 | class customerEdit: customer {
79 |
80 | var callBtn : XCUIElement {
81 | return self.btnWithText("Call")
82 | }
83 |
84 | var emailBtn : XCUIElement {
85 | return self.btnWithText("Email")
86 | }
87 |
88 | var locateBtn : XCUIElement {
89 | return self.btnWithText("Locate")
90 | }
91 |
92 | var relatedContactsCell : XCUIElement {
93 | return app.tables.staticTexts["Related Contacts"]
94 | }
95 |
96 | var generalInfoNavBtn : XCUIElement {
97 | return app.buttons["split1-editBtn"]
98 | }
99 |
100 | var contactInfoNavBtn : XCUIElement {
101 | return app.buttons["split2-editBtn"]
102 | }
103 |
104 | var addActivityBtn : XCUIElement {
105 | return app.tables.buttons["Add Activity"]
106 | }
107 |
108 | var detailsNavBtn : XCUIElement {
109 | return app.otherElements["creationInfo"].buttons.element
110 | }
111 |
112 | var infoPickerCancelView : XCUIElement {
113 | return app.otherElements["infoPickerCancelView"]
114 | }
115 |
116 | func mainContactCell(_ identifier:String) -> XCUIElement {
117 | let predicate = NSPredicate(format: "label CONTAINS[CD] %@",identifier)
118 | return app.tables.staticTexts.matching(predicate).element
119 | }
120 |
121 | func btnWithText(_ text: String) -> XCUIElement{
122 | return app.buttons[text]
123 | }
124 |
125 | func changeMainContactTo(_ identifier:String) {
126 | // self.relatedContactsCell.tap()
127 | // relatedContacts().setMainContact(identifier)
128 | // relatedContacts().leftMenuBtn.tap()
129 | self.rightMenuBtn.tap()
130 | app.buttons["Change Main Contact"].tap()
131 | relatedContacts().contactCell(identifier).tap()
132 | }
133 |
134 | func editCorporateContactInfo(name:String?=nil, officePhone:String?=nil, email:String?=nil, website:String?=nil) {
135 | self.generalInfoNavBtn.tap()
136 |
137 | if ((name) != nil) {
138 | let field = self.textFieldWithLabel(customer.CORPORATE_NAME)
139 | field.inputText(name!)
140 | }
141 |
142 | if ((officePhone) != nil) {
143 | let field = self.textFieldWithLabel(customer.OFFICE_PHONE)
144 | field.inputText(officePhone!)
145 | }
146 |
147 | if ((email) != nil) {
148 | let field = self.textFieldWithLabel(customer.EMAIL)
149 | field.inputText(email!)
150 | }
151 |
152 | if ((website) != nil) {
153 | let field = self.textFieldWithLabel(customer.WEBSITE)
154 | field.inputText(website!)
155 | }
156 |
157 | //save change
158 | app.buttons.element(boundBy: 1).tap()
159 | }
160 |
161 | func editIndividualGeneralInfo(firstName:String?=nil, lastName:String?=nil, position:String?=nil, company:String?=nil) {
162 | self.generalInfoNavBtn.tap()
163 |
164 | if ((firstName) != nil) {
165 | let field = self.textFieldWithLabel(customer.FIRST_NAME)
166 | field.inputText(firstName!)
167 | }
168 |
169 | if ((lastName) != nil) {
170 | let field = self.textFieldWithLabel(customer.LAST_NAME)
171 | field.inputText(lastName!)
172 | }
173 |
174 | if (position != nil) {
175 |
176 | }
177 |
178 | if ((company) != nil) {
179 | let field = self.textFieldWithLabel(customer.COMPANY)
180 | field.inputText(company!)
181 | }
182 |
183 | //save change
184 | app.buttons.element(boundBy: 1).tap()
185 | }
186 |
187 | func editIndividualContactInfo(cellPhone:String?=nil, officePhone:String?=nil, email:String?=nil, website:String?=nil) {
188 | self.contactInfoNavBtn.tap()
189 |
190 | if ((cellPhone) != nil) {
191 | let field = self.textFieldWithLabel(customer.CELLPHONE)
192 | field.inputText(cellPhone!)
193 | }
194 |
195 | if ((officePhone) != nil) {
196 | let field = self.textFieldWithLabel(customer.OFFICE_PHONE)
197 | field.inputText(officePhone!)
198 | }
199 |
200 | if ((email) != nil) {
201 | let field = self.textFieldWithLabel(customer.EMAIL)
202 | field.inputText(email!)
203 | }
204 |
205 | if ((website) != nil) {
206 | let field = self.textFieldWithLabel(customer.WEBSITE)
207 | field.inputText(website!)
208 | }
209 |
210 | //save change
211 | app.buttons.element(boundBy: 1).tap()
212 | }
213 |
214 | func editStatus(_ status: String) {
215 | self.generalInfoNavBtn.tap()
216 |
217 | let statusSwitch = app.tables.cells.containing(.staticText, identifier: customer.STATUS).staticTexts.element(boundBy: 1)
218 | statusSwitch.tap()
219 | app.pickerWheels.element.adjust(toPickerWheelValue: status)
220 | app.buttons["picker_confirm"].tap()
221 |
222 | //save change
223 | app.buttons["edit_confirm_btn"].tap()
224 | }
225 |
226 | func createOpportunity() {
227 | self.rightMenuBtn.tap()
228 | self.btnWithText("Create Opportunity").tap()
229 | }
230 |
231 | func cellOnInfoPickerView(_ identifier: String) -> XCUIElement {
232 | return self.cell(identifier, tableIdentifier: "infoPickerTable")
233 | }
234 | }
235 |
236 | class customerCreate : customer {
237 | var corporateName : XCUIElement {
238 | return self.textFieldWithLabel(customer.CORPORATE_NAME)
239 | }
240 | }
241 |
242 |
243 |
--------------------------------------------------------------------------------
/addressBook/relatedContacts.swift:
--------------------------------------------------------------------------------
1 | //
2 | // relatedContacts.swift
3 | // anwstream
4 | //
5 | //
6 | //
7 | //
8 |
9 | import Foundation
10 | import XCTest
11 |
12 | class relatedContacts: NSObject {
13 | let app = utils().app
14 |
15 | var leftMenuBtn : XCUIElement {
16 | return app.navigationBars.element.buttons.element(boundBy: 0)
17 | }
18 |
19 | var rightMenuBtn : XCUIElement {
20 | return app.navigationBars.element.buttons.element(boundBy: 1)
21 | }
22 |
23 | func contactCell(_ identifier: String) -> XCUIElement {
24 | return app.tables.cells.staticTexts[identifier]
25 | }
26 |
27 | func setMainContact(_ identifier:String) {
28 | self.contactCell(identifier).tap()
29 | contactEdit().rightMenuBtn.tap()
30 | contactEdit().btnWithText("Set as Main Contact").tap()
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/extensions/XCUIElement+TCEExt.swift:
--------------------------------------------------------------------------------
1 | //
2 | // XCUIElement+TCEExt.swift
3 | // anwstream
4 | //
5 | //
6 | //
7 | //
8 |
9 | import Foundation
10 | import XCTest
11 |
12 | extension XCUIElement {
13 | /**
14 | Removes any current text in the field before typing in the new value
15 | - Parameter text: the text to enter into the field
16 | */
17 | func clearAndEnterText(_ text: String, tapType: String?=nil, vector:CGVector? = nil) -> Void {
18 | guard let stringValue = self.value as? String else {
19 | XCTFail("Tried to clear and enter text into a non string value")
20 | return
21 | }
22 | if tapType == "forceTap"{
23 | self.forceTap(vector)
24 | } else {
25 | self.tap()
26 | }
27 | let deleteString = stringValue.characters.map { _ in XCUIKeyboardKeyDelete }.joined(separator: "")
28 | self.typeText(deleteString)
29 | self.typeText(text)
30 | }
31 |
32 | func forceTap(_ vector:CGVector? = nil){
33 | let coordinate = self.coordinate(withNormalizedOffset: ((vector == nil) ? CGVector(dx: 0, dy: 0) : vector!))
34 | coordinate.tap()
35 | }
36 |
37 | func smartTap(){
38 | self.tap();
39 | if(self.visible()){
40 | self.tap()
41 | }
42 | }
43 |
44 | func verifyExists(_ message: String = "Can not find related element") {
45 | XCTAssert(self.exists,message)
46 | }
47 |
48 | func verifyNotExists(_ message: String = "Related element still appears") {
49 | XCTAssertTrue(!self.exists, message)
50 | }
51 |
52 | func verifyEnabled(_ message: String = "Element disabled") {
53 | XCTAssert(self.isEnabled, message)
54 | }
55 |
56 | func verifyDisabled(_ message: String = "Element enabled") {
57 | XCTAssert(!self.isEnabled, message)
58 | }
59 |
60 | func verifyLabel(label : String, message: String = "Do not match text") {
61 | XCTAssertTrue(label == self.label, message)
62 | }
63 |
64 | func verifyTextValue(value : String, message: String = "Do not match text") {
65 | XCTAssertTrue(value == self.value as! String)
66 | }
67 |
68 | func inputText(_ text:String) {
69 | self.tap()
70 | self.clearAndEnterText(text)
71 | utils().handleKeyboard("Done")
72 | }
73 | }
74 |
--------------------------------------------------------------------------------
/home/home.swift:
--------------------------------------------------------------------------------
1 | //
2 | // home.swift
3 | // anwstream
4 | //
5 | // Created by Lu, Luis on 08/11/2016.
6 | //
7 | //
8 |
9 | import Foundation
10 | import XCTest
11 |
12 | class home: NSObject{
13 | let app = utils().app
14 |
15 | var searchButton: XCUIElement {
16 | return app.navigationBars.buttons.element(boundBy: 1)
17 | //return app.buttons["search_button"]
18 | }
19 |
20 | var homeTitle: XCUIElement {
21 | return app.navigationBars["home_nav_bar"]
22 | }
23 |
24 | func waitForViewDisplays(_ xcTestCase:XCTestCase) {
25 | utils().waitForElementToAppear(xcTestCase, homeTitle, timeout: 10)
26 | snapshot("homeScreen")
27 | }
28 |
29 | func verifyCardExisting(_ label: String) {
30 | let card = app.staticTexts[label];
31 | XCTAssertNotNil(card);
32 | }
33 |
34 | }
35 |
--------------------------------------------------------------------------------
/home/siderBar.swift:
--------------------------------------------------------------------------------
1 | //
2 | // siderBar.swift
3 | // anwstream
4 | //
5 | // Created by Lu, Luis on 10/11/2016.
6 | //
7 | //
8 |
9 | import Foundation
10 | import XCTest
11 |
12 |
13 | class siderBar: NSObject{
14 |
15 | let app = utils().app
16 |
17 | var homeMenuBtn: XCUIElement {
18 | return app.navigationBars.buttons.element(boundBy: 0)
19 | }
20 |
21 | var homeMenuBtnInHome: XCUIElement {
22 | return app.buttons["home_menu"]
23 | }
24 |
25 | /**
26 | - parameter boName: Home, Contacts, Products, Opportunities, Activities, Pipeline Overview, Sales Outlook, Settings, Sync, Logout
27 | */
28 | func navigateToBO(_ boName: String) {
29 | homeMenuBtn.forceTap()
30 | snapshot("siderBarMenuScreen")
31 | app.tables.staticTexts[boName].tap()
32 | }
33 |
34 | func logout(){
35 | navigateToBO("Settings")
36 | settings().navigate("My Profile")
37 | settings().btnWithText("Log Out")
38 | app.tap() // workaround to interact with the app again for the alter handler to fire
39 | }
40 |
41 | }
42 |
--------------------------------------------------------------------------------
/lead/lead.swift:
--------------------------------------------------------------------------------
1 | //
2 | // lead.swift
3 | // anwstream
4 | //
5 | //
6 | //
7 | //
8 |
9 | import Foundation
10 | import XCTest
11 |
12 | class lead: NSObject {
13 | static let STATUS = "Status"
14 | static let DESCRIPTION = "Description"
15 | static let SOURCE = "Source"
16 | static let QUALIFICATION = "Qualification"
17 | static let REMARKS = "Remarks"
18 | static let PHONE = "Phone"
19 | static let CELLPHONE = "Cellphone"
20 | static let EMAIL = "Email"
21 |
22 | let app = utils().app
23 |
24 | var leftMenuBtn: XCUIElement {
25 | return app.navigationBars.element.buttons.element(boundBy: 0)
26 | }
27 |
28 | var rightMenuBtn: XCUIElement {
29 | return app.navigationBars.element.buttons.element(boundBy: 1)
30 | }
31 |
32 | var contactEmail: XCUIElement {
33 | return self.buttonWithText("Email")
34 | }
35 |
36 | var contactCall: XCUIElement {
37 | return self.buttonWithText("Call")
38 | }
39 |
40 | var contactLocate: XCUIElement {
41 | return self.buttonWithText("Locate")
42 | }
43 |
44 | var addActivityBtn: XCUIElement {
45 | return self.buttonWithText("Add Activity")
46 | }
47 |
48 | var addAddressBtn : XCUIElement {
49 | return self.buttonWithText("Add Address")
50 | }
51 |
52 | var generalInfoNavBtn : XCUIElement {
53 | return self.buttonWithText("split1-editBtn")
54 | }
55 |
56 | var contactInfoNavBtn : XCUIElement {
57 | return self.buttonWithText("split2-editBtn")
58 | }
59 |
60 | var infoPickerCancelView : XCUIElement {
61 | return app.otherElements["infoPickerCancelView"]
62 | }
63 |
64 | var status: XCUIElement {
65 | return self.cell(lead.STATUS).staticTexts.element(boundBy: 2)
66 | }
67 |
68 | var descriptionField: XCUIElement {
69 | return self.textFieldWithLabel(lead.DESCRIPTION)
70 | }
71 |
72 | func textFieldWithLabel(_ identifier: String, index: UInt = 0) -> XCUIElement {
73 | return self.cell(identifier).textFields.element(boundBy: index)
74 | }
75 |
76 | func buttonWithText(_ identifier: String) -> XCUIElement {
77 | return app.buttons[identifier]
78 | }
79 |
80 | func swipeToActivity(){
81 | utils().swipeUpUntilElementVisible(element: lead().addActivityBtn)
82 | utils().swipeUp()
83 | }
84 |
85 | func swipeToAddress(){
86 | utils().swipeUpUntilElementVisible(element: lead().addAddressBtn)
87 | utils().swipeUp()
88 | }
89 |
90 | func cell(_ identifier: String, tableIdentifier:String? = nil) -> XCUIElement {
91 | let predicate = NSPredicate(format: "label CONTAINS[CD] %@",identifier)
92 | var table : XCUIElement;
93 | if (tableIdentifier == nil) {
94 | table = app.tables.element
95 | } else {
96 | table = app.tables[tableIdentifier!]
97 | }
98 | return table.cells.containing(predicate).element(boundBy: 0)
99 | }
100 |
101 | func deleteCell(_ identifier:String) {
102 | self.cell(identifier).swipeLeft()
103 | snapshot("deleteCell")
104 | self.cell(identifier).buttons["Delete"].tap()
105 | }
106 |
107 | func cellOnInfoPickerView(_ identifier: String) -> XCUIElement {
108 | return self.cell(identifier, tableIdentifier: "infoPickerTable")
109 | }
110 |
111 | func changeStatus(_ status: String) {
112 | self.status.tap()
113 | utils().handleSelectorPicker(status)
114 | }
115 |
116 | func textWithLabel(_ label:String) -> XCUIElement {
117 | return self.cell(label).staticTexts.element(boundBy: 1)
118 | }
119 |
120 | func editGeneralInfo(source: String?=nil, qualification: String?=nil, remarks: String?=nil
121 | ){
122 | self.generalInfoNavBtn.tap()
123 | if (source != nil) {
124 | self.cell(lead.STATUS).tap()
125 | utils().handleSelectorPicker(source!)
126 | }
127 |
128 | if (qualification != nil) {
129 | self.cell(lead.QUALIFICATION).tap()
130 | utils().handleSelectorPicker(qualification!)
131 | }
132 |
133 | if (remarks != nil) {
134 | let remarkTextView = self.cell(lead.REMARKS).textViews.element(boundBy: 0)
135 | remarkTextView.clearAndEnterText(remarks!, tapType: "forceTap", vector: CGVector.init(dx: 0.9, dy: 0.9))
136 | utils().handleKeyboard("Done")
137 | }
138 |
139 | //save change
140 | app.buttons.element(boundBy: 1).tap()
141 | }
142 |
143 | func editContactInfo(phone: String? = nil, cellPhone: String? = nil, email: String? = nil) {
144 | self.contactInfoNavBtn.tap()
145 | if (phone != nil) {
146 | let field = self.cell(lead.PHONE).textFields.element
147 | field.inputText(phone!)
148 | }
149 |
150 | if (cellPhone != nil) {
151 | let field = self.cell(lead.CELLPHONE).textFields.element
152 | field.inputText(cellPhone!)
153 | }
154 |
155 | if (email != nil) {
156 | let field = self.cell(lead.EMAIL).textFields.element
157 | field.inputText(email!)
158 | }
159 |
160 | //save change
161 | app.buttons.element(boundBy: 1).tap()
162 | }
163 | }
164 |
--------------------------------------------------------------------------------
/lead/leadsFilter.swift:
--------------------------------------------------------------------------------
1 | //
2 | // leadsFilter.swift
3 | // anwstream
4 | //
5 | //
6 | //
7 | //
8 |
9 | import Foundation
10 | import XCTest
11 |
12 | class leadsFilter : NSObject {
13 | let app = utils().app
14 |
15 | var filterBtn : XCUIElement {
16 | return app.buttons["Filter"]
17 | }
18 |
19 | var sortTabBtn : XCUIElement {
20 | return app.buttons["Sort"]
21 | }
22 |
23 | var filterTable : XCUIElement {
24 | return app.tables["filterTable"]
25 | }
26 |
27 | var sortTable : XCUIElement {
28 | return app.tables["sortTable"]
29 | }
30 |
31 | var resetBtn : XCUIElement {
32 | return app.buttons["Reset"]
33 | }
34 |
35 | var applyBtn : XCUIElement {
36 | return app.buttons["Apply"]
37 | }
38 |
39 | func filterValue(_ categoryName: String, value: String) -> XCUIElement {
40 | return self.filterTable.cells.containing(.staticText, identifier: categoryName).staticTexts[value]
41 | }
42 |
43 | func applyFilter(owner: String?=nil, statuses: NSArray?=nil, qualification: String?=nil) {
44 | if (owner != nil) {
45 | filterValue("Owner", value: owner!).tap()
46 | }
47 |
48 | if (statuses != nil) {
49 | for statusValue in statuses! {
50 | filterValue("Status", value: statusValue as! String).tap()
51 | }
52 | }
53 |
54 | if (qualification != nil) {
55 | filterValue("Qualification", value: qualification!).tap()
56 | }
57 |
58 | self.applyBtn.tap()
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/lead/leadsList.swift:
--------------------------------------------------------------------------------
1 | //
2 | // leadsList.swift
3 | // anwstream
4 | //
5 | //
6 | //
7 | //
8 |
9 | import Foundation
10 | import XCTest
11 |
12 | class leadsList : NSObject {
13 | let app = utils().app
14 | static let LIST_TITLE = "Leads"
15 |
16 | var leftMenuBtn : XCUIElement {
17 | return app.navigationBars.element.buttons.element(boundBy: 0)
18 | }
19 |
20 | var openQuickFilterBtn: XCUIElement {
21 | return app.buttons["Open"]
22 | }
23 |
24 | var newQuickFilterBtn: XCUIElement {
25 | return app.buttons["New"]
26 | }
27 |
28 | var allQuickFilterBtn : XCUIElement {
29 | return app.buttons["All"]
30 | }
31 |
32 | var filterBtn : XCUIElement {
33 | return app.navigationBars[leadsList.LIST_TITLE].buttons["filterBtn"];
34 | }
35 |
36 | var createBtn : XCUIElement {
37 | return app.navigationBars[leadsList.LIST_TITLE].buttons["createBtn"];
38 | }
39 |
40 | var searchField : XCUIElement {
41 | return app.searchFields.element
42 | }
43 |
44 | func cellWithText(_ identifier: String) -> XCUIElement{
45 | return app.tables.cells.staticTexts[identifier]
46 | }
47 |
48 | func searchAndGoToDetail(_ identifier:String) {
49 | self.searchField.tap()
50 | self.searchField.typeText(identifier)
51 | utils().handleKeyboard("Search")
52 | self.cellWithText(identifier).tap()
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/login/login.swift:
--------------------------------------------------------------------------------
1 | //
2 | // login.swift
3 | // anwstream
4 | //
5 | // Created by Lu, Luis on 07/11/2016.
6 | //
7 | //
8 |
9 |
10 | import Foundation
11 | import XCTest
12 |
13 | class login: NSObject{
14 | let app = utils().app
15 |
16 | var userNameField: XCUIElement {
17 | //return app.otherElements.matching(identifier: "user_email").children(matching: .textField).element
18 | return app.textFields.element
19 | }
20 |
21 | var passwordField: XCUIElement {
22 | //return app.otherElements.matching(identifier: "user_password").children(matching: .secureTextField).element
23 | return app.secureTextFields.element
24 | }
25 |
26 | var loginButton: XCUIElement {
27 | return app.buttons["Login"]
28 | }
29 |
30 | var switchServerLink: XCUIElement {
31 | return app.buttons["switch environment"]
32 | }
33 |
34 | func typeUserName(_ userName: String) {
35 | userNameField.clearAndEnterText(userName)
36 | }
37 |
38 | func typePassword(_ password: String) {
39 | passwordField.clearAndEnterText(password)
40 | }
41 |
42 | func switchServer(_ serverAddress: String){
43 | switchServerLink.tap()
44 | app.cells.staticTexts[serverAddress].tap()
45 | }
46 |
47 | func submitLogin(){
48 | loginButton.tap()
49 | }
50 |
51 | func normalLogin(_ serverAddress: String, _ userName: String?=nil, _ password: String?=nil){
52 | switchServer(serverAddress)
53 | snapshot("loginScreen")
54 | if serverAddress != "Test"{
55 | typeUserName(userName!)
56 | typePassword(password!)
57 | }
58 | submitLogin()
59 | }
60 |
61 | func waitForViewDisplays(_ xcTestCase:XCTestCase){
62 | utils().waitForElementToAppear(xcTestCase,userNameField)
63 | }
64 |
65 | }
66 |
--------------------------------------------------------------------------------
/opportunity/opportunitiesFilter.swift:
--------------------------------------------------------------------------------
1 | //
2 | // opportunitiesFilter.swift
3 | // anwstream
4 | //
5 | // Created by Lu, Luis on 05/12/2016.
6 | //
7 | //
8 |
9 | import Foundation
10 | import XCTest
11 |
12 | class opportunitiesFilter: NSObject{
13 | let app = utils().app
14 |
15 | func selectStages(_ stagesList:Array){
16 | //expand stags section if needed
17 | // var btn = app.tables.cells.containing(.staticText, identifier: "Stage").buttons.element(boundBy: 0).tap()
18 | for stage in stagesList{
19 | app.tables.cells.containing(.staticText, identifier: "Stage").staticTexts[stage].tap()
20 | }
21 | }
22 |
23 | // func selectStatus(_ status:String){
24 | // app.tables.cells.staticTexts[status].tap()
25 | // }
26 | //
27 | func selectCustomer(_ customer:String){
28 | app.tables.cells.containing(.staticText, identifier: "Customer").staticTexts[customer].tap()
29 | }
30 |
31 | func selectPotentialAmountRange(_ minMaxPotentialAmount:Array){
32 | app.tables.cells.containing(.staticText, identifier: "Potential Amount").textFields.element(boundBy: 0).tap()
33 | app.tables.cells.containing(.staticText, identifier: "Potential Amount").textFields.element(boundBy: 0).typeText(minMaxPotentialAmount[0])
34 | app.tables.cells.containing(.staticText, identifier: "Potential Amount").textFields.element(boundBy: 1).tap()
35 | app.tables.cells.containing(.staticText, identifier: "Potential Amount").textFields.element(boundBy: 1).typeText(minMaxPotentialAmount[1])
36 | utils().handleKeyboard("Done")
37 | }
38 |
39 | func clickResetBtn(){
40 | app.buttons["resetBtn"].tap()
41 | }
42 |
43 | func clickApplyBtn(){
44 | app.buttons["applyBtn"].tap()
45 | }
46 |
47 | func apply(_ stageList:Array?=nil,_ customer:String?=nil,_ minMaxPotentialAmount:Array?=nil ) {
48 | if stageList != nil {
49 | selectStages(stageList!)
50 | }
51 | // if status != nil {
52 | // selectStatus(status!)
53 | // }
54 | if customer != nil {
55 | selectCustomer(customer!)
56 | }
57 | if minMaxPotentialAmount != nil {
58 | selectPotentialAmountRange(minMaxPotentialAmount!)
59 | }
60 | clickApplyBtn()
61 | }
62 |
63 | }
64 |
--------------------------------------------------------------------------------
/opportunity/opportunitiesList.swift:
--------------------------------------------------------------------------------
1 | //
2 | // opportunitiesList.swift
3 | // anwstream
4 | //
5 | // Created by Lu, Luis on 08/11/2016.
6 | //
7 | //
8 |
9 | import Foundation
10 | import XCTest
11 |
12 | class opportunitiesList: NSObject{
13 | let app = utils().app
14 |
15 | var createOppBtn: XCUIElement {
16 | //return app.navigationBars["Opportunities"].buttons.element(boundBy: 1)
17 | return app.navigationBars["Opportunities"].buttons["opportunityCreateBtn"]
18 | }
19 |
20 | var oppFilterBtn: XCUIElement {
21 | //return app.navigationBars["Opportunities"].buttons.element(boundBy: 1)
22 | return app.navigationBars["Opportunities"].buttons["opportunityFilterBtn"]
23 | }
24 |
25 | var opportunitiesTitle: XCUIElement {
26 | return app.staticTexts["Opportunities"]
27 | }
28 |
29 |
30 | func clickCreateOppBtn(){
31 | createOppBtn.tap()
32 | }
33 |
34 | func clickOppFilterBtn(){
35 | oppFilterBtn.tap()
36 | }
37 |
38 | /**
39 | - parameter timeOption: Week, Month, All
40 | */
41 | func switchTimeInterval(_ timeOption:String){
42 | app.buttons[timeOption].tap()
43 | }
44 |
45 | func waitForViewDisplays(_ xcTestCase:XCTestCase) {
46 | utils().waitForElementToAppear(xcTestCase, opportunitiesTitle, timeout: 10)
47 | snapshot("opportunitiesListScreen")
48 | }
49 |
50 | /**
51 | - parameter identifier: partial matching any value displays in opportunity card
52 | */
53 | func goToDetailedView(_ identifier: String){
54 | let oppPartialValue = NSPredicate(format: "label CONTAINS[CD] %@",identifier)
55 | app.tables.cells.containing(.staticText, identifier: "Stage updated today").staticTexts.matching(oppPartialValue).element.tap()
56 | snapshot("opportunityDetailsScreen")
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/opportunity/opportunity.swift:
--------------------------------------------------------------------------------
1 | //
2 | // opportunitiesDetails.swift
3 | // anwstream
4 | //
5 | // Created by Lu, Luis on 08/11/2016.
6 | //
7 | //
8 |
9 | import Foundation
10 | import XCTest
11 |
12 | class opportunity: NSObject{
13 | let app = utils().app
14 |
15 | var leftMenuBtn: XCUIElement {
16 | return app.navigationBars.element.buttons.element(boundBy: 0)
17 | }
18 |
19 | var rightMenuBtn: XCUIElement {
20 | return app.navigationBars.element.buttons.element(boundBy: 1)
21 | }
22 |
23 | var contactEmail: XCUIElement {
24 | return app.buttons["Email"]
25 | }
26 | var contactCall: XCUIElement {
27 | return app.buttons["Call"]
28 | }
29 | var contactLocate: XCUIElement {
30 | return app.buttons["Locate"]
31 | }
32 |
33 | var addActivityBtn: XCUIElement {
34 | return app.tables.buttons["Add Activity"]
35 | }
36 |
37 | var addProductBtn: XCUIElement {
38 | return app.tables.buttons["Add Product"]
39 | }
40 | var status: XCUIElement {
41 | return app.tables.cells.containing(.staticText, identifier: "Status").staticTexts.element(boundBy: 2)
42 | }
43 |
44 | var stage: XCUIElement {
45 | return app.tables.cells.containing(.staticText, identifier: "Stage").staticTexts.element(boundBy: 2)
46 | }
47 |
48 | var oppInformationNavBtn: XCUIElement {
49 | return app.otherElements.containing(.staticText, identifier: "Basic Information").children(matching: .button).element
50 | }
51 |
52 | var infoPickerCancelView : XCUIElement {
53 | return app.otherElements["infoPickerCancelView"]
54 | }
55 |
56 | func changeStage(_ stage:String){
57 | self.stage.tap()
58 | if (!app.tables.staticTexts.matching(identifier: stage).element.exists) {
59 | self.stage.tap()
60 | }
61 | app.tables.staticTexts.matching(identifier: stage).element(boundBy: 0).tap()
62 | app.buttons.element(boundBy: 1).tap()
63 | }
64 |
65 | func changeStatus(_ status:String, reason:String){
66 | self.status.tap()
67 | if (!app.tables.staticTexts.matching(identifier: status).element.exists) {
68 | self.status.tap()
69 | }
70 | app.tables.staticTexts.matching(identifier: status).element(boundBy: 0).tap()
71 | app.buttons.element(boundBy: 1).tap()
72 | app.tables.staticTexts.matching(identifier: reason).element(boundBy: 0).tap()
73 | app.buttons.element(boundBy: 1).tap()
74 | }
75 |
76 | func editInformation(_ potentialAmount:String?=nil, startDate:String?=nil, closingPercentage:String?=nil){
77 | self.oppInformationNavBtn.tap()
78 | if startDate != nil {
79 | utils().handleDatePicker(app.tables.cells.containing(.staticText, identifier: "Start Date").staticTexts.element(boundBy: 1) , date: startDate!)
80 | }
81 | if potentialAmount != nil {
82 | app.tables.cells.containing(.staticText, identifier: "Potential Amount").textFields.element.tap()
83 | app.tables.cells.containing(.staticText, identifier: "Potential Amount").textFields.element.typeText(potentialAmount!)
84 | utils().handleKeyboard("Done")
85 | }
86 |
87 | if closingPercentage != nil {
88 | app.tables.cells.containing(.staticText, identifier: "Closing Percentage").textFields.element.tap()
89 | app.tables.cells.containing(.staticText, identifier: "Closing Percentage").textFields.element.typeText(closingPercentage!)
90 | utils().handleKeyboard("Done")
91 | }
92 | app.buttons.element(boundBy: 1).tap()
93 | }
94 |
95 |
96 | func delActivity(_ activityList:Array){
97 | opportunity().scrollToCreateActivity()
98 | for oneActivity in activityList {
99 | let activity = app.tables.cells.staticTexts[oneActivity]
100 | activity.swipeLeft()
101 | snapshot("deleteActivityScreen1")
102 | // let start = activity.coordinate(withNormalizedOffset:CGVector(dx: 0, dy: 0))
103 | // let finish = activity.coordinate(withNormalizedOffset:CGVector(dx: -60, dy: 0))
104 | // start.press(forDuration: 0, thenDragTo: finish)
105 | app.tables.cells.containing(.staticText, identifier: oneActivity).buttons["Delete"].tap()
106 | }
107 | }
108 |
109 | func delProduct(_ productList:Array){
110 | for oneProduct in productList {
111 | let product = app.tables.cells.staticTexts[oneProduct]
112 | product.swipeLeft()
113 | app.tables.cells.containing(.staticText, identifier: oneProduct).buttons["Delete"].tap()
114 | }
115 | }
116 |
117 |
118 |
119 | func addProduct(_ productName:String, unitPrice:String?=nil, quantity:String?=nil, discount:String?=nil){
120 | addProductBtn.tap()
121 | //app.searchFields["Search"].forceTap()
122 | //app.searchFields["Search"].typeText(productName)
123 | //utils().handleKeyboard("Search")
124 | app.tables.cells.staticTexts[productName].forceTap()
125 | //
126 | // if unitPrice != nil {
127 | // app.textFields["unitPriceField"].clearAndEnterText(unitPrice!, tapType: "forceTap")
128 | // utils().handleKeyboard("Done")
129 | // }
130 | //
131 | // if quantity != nil {
132 | // app.textFields["quantityField"].forceTap()
133 | // app.textFields["quantityField"].clearAndEnterText(quantity!)
134 | // utils().handleKeyboard("Done")
135 | // }
136 | //
137 | // if discount != nil {
138 | // app.textFields["discountField"].forceTap()
139 | // app.textFields["discountField"].clearAndEnterText(discount!)
140 | // utils().handleKeyboard("Done")
141 | // }
142 | //
143 | // let expectedTotal:String = app.textFields["unitPriceField"].value as! String
144 | // XCTAssertTrue(expectedTotal == app.staticTexts["totalMoney"].label, "Total money \(status) is not correct")
145 |
146 | app.buttons["Add to Opportunity"].tap()
147 | app.navigationBars.buttons.element(boundBy: 0).tap()
148 | app.navigationBars.buttons.element(boundBy: 0).tap()
149 | ()
150 | }
151 |
152 |
153 |
154 | /**
155 | - parameter SKUsArrayList: format sku name + total as one array record in a multidimensional arrays.
156 | e.g [["abc","¥100"],["ddd","¥200"]]
157 | */
158 | func verifySKUsDisplay(_ SKUsArrayList:Array>){
159 | for sku in SKUsArrayList {
160 | for item in sku {
161 | app.tables.cells.staticTexts[item].verifyExists()
162 | }
163 | }
164 | }
165 |
166 | func verifySKUsDisapper(_ SKUList:Array){
167 | for sku in SKUList{
168 | app.tables.staticTexts[sku].verifyNotExists("SKU \(sku) should not exists ")
169 | }
170 |
171 | }
172 |
173 | func verifySKUTotal(_ total:String){
174 | app.tables.cells.containing(.staticText, identifier: "Total").staticTexts[total].verifyExists("Total \(total) money is not correct ")
175 | }
176 |
177 | /**
178 | - parameter identifier: partial matching any value displays in opportunity detailed view
179 | */
180 | func verifyActivityDisplays(_ activityText:String){
181 | let activityPartialValue = NSPredicate(format: "label CONTAINS[CD] %@",activityText)
182 | app.tables.staticTexts.matching(activityPartialValue).element.verifyExists("Can't found expected \(activityText) opportunity ")
183 | }
184 |
185 | func verifyActivityDisappers(_ activityText:String){
186 | let activityPartialValue = NSPredicate(format: "label CONTAINS[CD] %@",activityText)
187 | app.tables.staticTexts.matching(activityPartialValue).element.verifyNotExists("Activity \(activityText) should not exists ")
188 | }
189 |
190 |
191 | func verifyWeightAmount(_ weightAmount:String){
192 | app.tables.cells.containing(.staticText, identifier: "Weighted Amount").staticTexts[weightAmount].verifyExists("WeightAmount \(weightAmount) is not correct")
193 | }
194 |
195 |
196 | func verifyStatus(_ status:String){
197 | XCTAssertTrue(status==self.status.label, "Current status \(status) is not correct")
198 | }
199 |
200 | func verifyStage(_ stage:String){
201 | XCTAssertTrue(stage==self.stage.label, "Current stage \(stage) is not correct")
202 |
203 | }
204 |
205 | private func cellOnInfoPickerView(_ identifier: String) -> XCUIElement {
206 | return self.cell(identifier, tableIdentifier: "infoPickerTable")
207 | }
208 |
209 | private func cell(_ identifier: String, tableIdentifier:String? = nil) -> XCUIElement {
210 | let predicate = NSPredicate(format: "label CONTAINS[CD] %@",identifier)
211 | var table : XCUIElement;
212 | if (tableIdentifier == nil) {
213 | table = app.tables.element
214 | } else {
215 | table = app.tables[tableIdentifier!]
216 | }
217 | return table.staticTexts.matching(predicate).element
218 | }
219 |
220 | func verifyContactCall(_ callList:Array?=nil){
221 | if self.contactCall.isEnabled == true && callList != nil {
222 | self.contactCall.tap()
223 | for call in callList!{
224 | self.cellOnInfoPickerView(call).verifyExists("Call \(call) doesn't display")
225 | }
226 | }
227 | self.infoPickerCancelView.tap()
228 | }
229 |
230 | func verifyContactEmail(_ email:String?=nil){
231 | if self.contactEmail.isEnabled == true && email != nil {
232 | self.contactEmail.tap()
233 | self.cellOnInfoPickerView(email!).verifyExists("Email \(email) doesn't display")
234 | }
235 | self.infoPickerCancelView.tap()
236 | }
237 |
238 | func verifyContactLocate(_ locate:String?=nil){
239 | if self.contactLocate.isEnabled == true && locate != nil {
240 | self.contactLocate.tap()
241 | self.cellOnInfoPickerView(locate!).verifyExists("Locate \(locate) doesn't display")
242 | }
243 | self.infoPickerCancelView.tap()
244 | }
245 |
246 | func scrollToCreateActivity(){
247 | utils().swipeUpUntilElementVisible(element: opportunity().addActivityBtn)
248 | utils().swipeUp()
249 | }
250 |
251 |
252 | }
253 |
--------------------------------------------------------------------------------
/product/product.swift:
--------------------------------------------------------------------------------
1 | //
2 | // product.swift
3 | // anwstream
4 | //
5 | //
6 | //
7 | //
8 |
9 | import Foundation
10 | import XCTest
11 |
12 | class product : NSObject {
13 |
14 | let app = utils().app;
15 |
16 | func waitForViewDisplays(_ xcTestCase:XCTestCase, _ label: String) {
17 | let labelControl = app.staticTexts[label];
18 | utils().waitForElementToAppear(xcTestCase, labelControl, timeout: 10);
19 | }
20 |
21 | /**
22 | * verify cell value, layout structure should like below
23 | * [Cell]
24 | * [StaticText] - cellName
25 | * [StaticText] - value
26 | */
27 | func verifyCellValue(_ cellName:String, _ value: String) {
28 | app.tables.cells.containing(.staticText, identifier: cellName).staticTexts[value].verifyExists("\(cellName) value \(value) is not correct");
29 | }
30 |
31 | }
32 |
33 |
--------------------------------------------------------------------------------
/product/productFilter.swift:
--------------------------------------------------------------------------------
1 | //
2 | // productFilter.swift
3 | // anwstream
4 | //
5 | //
6 | //
7 | //
8 |
9 | import Foundation
10 | import XCTest
11 |
12 | class productFilter: NSObject{
13 | let app = utils().app;
14 |
15 | func clickResetBtn(){
16 | app.buttons["resetBtn"].tap()
17 | }
18 |
19 | func clickApplyBtn(){
20 | app.buttons["applyBtn"].tap()
21 | }
22 |
23 | func apply(_ category:String?=nil, _ brand:String?=nil, _ priceRange:Array?=nil) {
24 | if category != nil {
25 | selectCategory(category!);
26 | }
27 | if brand != nil {
28 | selectBrand(brand!);
29 | }
30 | if priceRange != nil {
31 | setPriceRange(priceRange!);
32 | }
33 | clickApplyBtn();
34 | }
35 |
36 | func selectCategory(_ category:String) {
37 | app.tables.cells.containing(.staticText, identifier: "Category").staticTexts[category].tap();
38 | }
39 |
40 | func selectBrand(_ brand:String) {
41 | app.tables.cells.containing(.staticText, identifier: "Brand").staticTexts[brand].tap();
42 | }
43 |
44 | func setPriceRange(_ priceRange:Array){
45 | app.tables.cells.containing(.staticText, identifier: "Price Range").textFields.element(boundBy: 0).tap();
46 | app.tables.cells.containing(.staticText, identifier: "Price Range").textFields.element(boundBy: 0).typeText(priceRange[0]);
47 | app.tables.cells.containing(.staticText, identifier: "Price Range").textFields.element(boundBy: 1).tap();
48 | app.tables.cells.containing(.staticText, identifier: "Price Range").textFields.element(boundBy: 1).typeText(priceRange[1]);
49 | utils().handleKeyboard("Done");
50 | }
51 |
52 | }
53 |
--------------------------------------------------------------------------------
/product/productList.swift:
--------------------------------------------------------------------------------
1 | //
2 | // productList
3 | // anwstream
4 | //
5 | //
6 | //
7 | //
8 |
9 | import Foundation
10 | import XCTest
11 |
12 | class productList : NSObject {
13 |
14 | let app = utils().app;
15 |
16 | var leftMenuBtn : XCUIElement {
17 | return app.navigationBars.element.buttons.element(boundBy: 0)
18 | }
19 |
20 | var filterBtn: XCUIElement {
21 | return app.navigationBars["Products"].buttons["productFilterBtn"];
22 | }
23 |
24 | func clickFilterBtn(){
25 | filterBtn.tap();
26 | }
27 |
28 | func findProductCell(_ identifier: String) -> XCUIElementQuery {
29 | return app.tables.cells.containing(.staticText, identifier: identifier);
30 | }
31 |
32 | func goToDetailedView(_ name: String) {
33 | app.staticTexts[name].forceTap();
34 | }
35 |
36 | func verifyProductExisting(_ identifier:String, _ isExisting:Bool) {
37 | let productCell = productList().findProductCell(identifier);
38 | if(isExisting == true){
39 | XCTAssertNotEqual(productCell.count, 0);
40 | }else{
41 | XCTAssertEqual(productCell.count, 0);
42 | }
43 |
44 | }
45 |
46 | }
47 |
--------------------------------------------------------------------------------
/profile/profile.swift:
--------------------------------------------------------------------------------
1 | //
2 | // profile.swift
3 | // anwstream
4 | //
5 | //
6 | //
7 | //
8 |
9 | import Foundation
10 | import XCTest
11 |
12 | class profile: NSObject{
13 |
14 | let app = utils().app
15 |
16 | var editBtn: XCUIElement {
17 | return app.navigationBars.buttons["profile_edit"];
18 | }
19 | var saveBtn: XCUIElement {
20 | return app.buttons["edit_confirm_btn"];
21 | }
22 |
23 | var backBtn: XCUIElement {
24 | return app.navigationBars.element.buttons.element(boundBy: 0)
25 | }
26 |
27 | func textWithLabel(_ label:String) -> XCUIElement {
28 | return app.tables.cells.containing(.staticText, identifier: label).staticTexts.element(boundBy: 1)
29 | }
30 |
31 | func textFieldWithLabel(_ label:String) -> XCUIElement {
32 | return app.tables.cells.containing(.staticText, identifier: label).textFields.element
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/reports/outlook.swift:
--------------------------------------------------------------------------------
1 | //
2 | // outlook.swift
3 | // anwstream
4 | //
5 | // on 2017/8/2.
6 | //
7 | //
8 |
9 | import Foundation
10 | import XCTest
11 |
12 | class outlook : NSObject {
13 |
14 | let app = utils().app
15 |
16 | static let OPPORTUNITIES_OUTLOOK_TITLE :String = "Opportunities Outlook"
17 |
18 | func pullDownMenu(_ itemName: String){
19 | app.buttons[itemName].tap()
20 | }
21 |
22 | func tapRow(_ text: String){
23 | app.buttons[text].tap()
24 | }
25 |
26 | func setFilter(_ itemName: String, _ text: String){
27 | self.pullDownMenu(itemName)
28 | self.tapRow(text)
29 | }
30 |
31 | }
32 |
--------------------------------------------------------------------------------
/reports/overview.swift:
--------------------------------------------------------------------------------
1 | //
2 | // overview.swift
3 | // anwstream
4 | //
5 | // on 2017/8/2.
6 | //
7 | //
8 |
9 | import Foundation
10 | import XCTest
11 |
12 | class overview : NSObject {
13 |
14 | let app = utils().app
15 |
16 | static let PIPELINE_OVERVIEW_TITLE :String = "Pipeline Overview"
17 |
18 | func pullDownMenu(_ itemName: String){
19 | app.buttons[itemName].tap()
20 | }
21 |
22 | func tapRow(_ text: String){
23 | app.buttons[text].tap()
24 | }
25 |
26 | func setFilter(_ itemName: String, _ text: String){
27 | self.pullDownMenu(itemName)
28 | self.tapRow(text)
29 | }
30 |
31 | }
32 |
--------------------------------------------------------------------------------
/reports/reportsList.swift:
--------------------------------------------------------------------------------
1 | //
2 | // reportsList.swift
3 | // anwstream
4 | //
5 | // on 2017/8/1.
6 | //
7 | //
8 |
9 | import Foundation
10 | import XCTest
11 |
12 | class reportsList : NSObject {
13 |
14 | let app = utils().app
15 |
16 | static let REPORTS_LIST_TITLE :String = "Reports"
17 |
18 | var leftMenuBtn : XCUIElement {
19 | return app.navigationBars.element.buttons.element(boundBy: 0)
20 | }
21 |
22 | func navigate(_ itemName: String){
23 | app.tables.cells.containing(.staticText, identifier:itemName).element.tap()
24 | }
25 |
26 | var backBtn: XCUIElement {
27 | return app.navigationBars.element.buttons.element(boundBy: 0)
28 | }
29 |
30 | }
31 |
--------------------------------------------------------------------------------
/reports/summary.swift:
--------------------------------------------------------------------------------
1 | //
2 | // summary.swift
3 | // anwstream
4 | //
5 | //
6 | //
7 | //
8 |
9 | import Foundation
10 | import XCTest
11 |
12 | class summary : NSObject {
13 |
14 | let app = utils().app
15 |
16 | static let SALES_SUMMARY_TITLE :String = "Sales Summary"
17 |
18 | func pullDownMenu(_ itemName: String){
19 | app.buttons[itemName].tap()
20 | }
21 |
22 | func tapRow(_ text: String){
23 | app.buttons[text].tap()
24 | }
25 |
26 | func unselectAll(_ unselectAll:String){
27 | app.buttons["multi_option_select_all"].tap()
28 | }
29 |
30 | func select(_ text: String){
31 | app.buttons[text].tap()
32 | }
33 |
34 | func setFilter(_ itemName: String, _ text: String){
35 | self.pullDownMenu(itemName)
36 | self.tapRow(text)
37 | }
38 |
39 | func multiSelect(_ unselectText: String, _ selectBtn: Array){
40 | self.unselectAll(unselectText)
41 |
42 | for text: String in selectBtn {
43 | self.select(text)
44 | }
45 |
46 | }
47 |
48 | var applyBtn : XCUIElement {
49 | return app.buttons["Apply"]
50 | }
51 |
52 | }
53 |
--------------------------------------------------------------------------------
/settings/settings.swift:
--------------------------------------------------------------------------------
1 | //
2 | // settings.swift
3 | // anwstream
4 | //
5 | //
6 | //
7 | //
8 |
9 | import Foundation
10 | import XCTest
11 |
12 | class settings: NSObject{
13 |
14 | let app = utils().app
15 |
16 | var backBtn:XCUIElement{
17 | return app.buttons["setting_form_back"]
18 | }
19 |
20 | func navigate(_ itemName: String){
21 | app.tables.cells.containing(.staticText, identifier:itemName).element.tap()
22 | }
23 |
24 | func toggleSwitch(key: String){
25 | // NSLog("%@", app.tables.checkBoxes.element(boundBy: 0))
26 | app.tables.cells.containing(.staticText, identifier:key).switches.element(boundBy: 0).tap()
27 | }
28 |
29 | func tapRow(_ text: String){
30 | app.tables.cells.containing(.staticText, identifier:text).element.tap()
31 | }
32 |
33 | func btnWithText(_ text: String){
34 | app.buttons[text].tap()
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/story.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Story.swift
3 | // anwstream
4 | //
5 | // Created by Lu, Luis on 07/11/2016.
6 | //
7 | //
8 |
9 | import XCTest
10 |
11 | class story: XCTestCase {
12 |
13 | var systemAlertMonitorToken: NSObjectProtocol? = nil
14 |
15 | override func setUp() {
16 | super.setUp()
17 |
18 | // Put setup code here. This method is called before the invocation of each test method in the class.
19 |
20 | // In UI tests it is usually best to stop immediately when a failure occurs.
21 | continueAfterFailure = false
22 | // UI tests must launch the application that they test. Doing this in setup will make sure it happens for each test method.
23 | let app = utils().app
24 | app.launchArguments = ["UI-TESTING"]
25 | setupSnapshot(app)
26 | print(app.launchArguments)
27 | app.launch()
28 | systemAlertMonitorToken = self.addUIInterruptionMonitor(withDescription: "HandleAlert") { (alert) -> Bool in
29 | if alert.buttons["OK"].exists {
30 | alert.buttons["OK"].tap()
31 | return true
32 | } else if alert.buttons["Ok"].exists {
33 | alert.buttons["Ok"].tap()
34 | return true
35 | } else {
36 | return false
37 | }
38 | }
39 | }
40 |
41 | override func tearDown() {
42 | if let systemAlertMonitorToken = self.systemAlertMonitorToken {
43 | removeUIInterruptionMonitor(systemAlertMonitorToken)
44 | }
45 | // Put teardown code here. This method is called after the invocation of each test method in the class.
46 | super.tearDown()
47 | }
48 |
49 | private func loginAndGoToList(_ listName:String) {
50 | //login
51 | login().normalLogin("Test")
52 | home().waitForViewDisplays(self)
53 |
54 | //navigate to list
55 | if(!listName.isEmpty){
56 | siderBar().navigateToBO(listName);
57 | }
58 | }
59 |
60 | private func logout() {
61 | siderBar().logout()
62 | login().waitForViewDisplays(self)
63 | }
64 |
65 | func testOpportunity() {
66 | self.loginAndGoToList("Opportunities")
67 |
68 | opportunitiesList().waitForViewDisplays(self)
69 | opportunitiesList().switchTimeInterval("All")
70 | opportunitiesList().clickOppFilterBtn()
71 | opportunitiesFilter().apply(["评估销售机会"], "James Leung", ["0","100"])
72 | opportunitiesList().goToDetailedView("James Leung")
73 |
74 | // Verify customer information in opportunity
75 | opportunity().verifyContactCall(["234567","123456"])
76 | opportunity().verifyContactEmail("test@126.com")
77 | opportunity().verifyContactLocate("chenhui road 1001")
78 |
79 | // Edit opportunity information
80 | opportunity().editInformation("10000", closingPercentage: "95")
81 | utils().app.tables.element.swipeUp()
82 | opportunity().verifyWeightAmount("¥9,500.00")
83 |
84 | // // Add one product
85 | // utils().app.tables.element.swipeUp()
86 | // opportunity().addProduct("abc", unitPrice: "10", quantity: "20", discount: "5")
87 | // opportunity().verifySKUsDisplay([["abc-Green","¥100"]])
88 | // opportunity().verifySKUTotal("¥100")
89 | //
90 | // // delete one product
91 | // opportunity().delProduct(["abc-Green"])
92 | // opportunity().verifySKUsDisapper(["abc-Green"])
93 |
94 | //Add one comment activity
95 | opportunity().scrollToCreateActivity()
96 | opportunity().addActivityBtn.tap()
97 | commentActivity().create("commentTest")
98 | opportunity().verifyActivityDisplays("commentTest")
99 |
100 | //Add one call activity
101 | opportunity().scrollToCreateActivity()
102 | opportunity().addActivityBtn.tap()
103 | callActivity().create("CallTest")
104 | opportunity().verifyActivityDisplays("CallTest")
105 |
106 | //Add one appointment activity
107 | opportunity().addActivityBtn.tap()
108 | appointmentActivity().add("11.11 meeting", "AppointmentTest",attendeeList:["Doe Jane"],location:"PVG03 B1.1")
109 | opportunity().verifyActivityDisplays("11.11 meeting")
110 |
111 | // Delete one activity
112 | opportunity().delActivity(["11.11 meeting"])
113 | opportunity().verifyActivityDisappers("11.11")
114 |
115 | //Edit opportunity stage, status
116 | utils().app.tables.element.swipeDown()
117 | opportunity().changeStage("销售订单")
118 | opportunity().verifyStage("销售订单")
119 | opportunity().changeStatus("Won", reason: "None")
120 | opportunity().verifyStatus("Won")
121 |
122 | //Logout
123 | opportunity().leftMenuBtn.tap()
124 | self.logout()
125 | }
126 |
127 |
128 | /**
129 | * equals /api/mobile/Employees/v1/me => get me
130 | * equals /api/mobile/Employees/v1 => get all employees, for sync employee coredate
131 | * startsWith /api/mobile/Employees/v1/{10086} => get single employee by id, used by user
132 | */
133 | func testSettings() {
134 | self.loginAndGoToList("Settings")
135 |
136 | //change profile
137 | settings().navigate("My Profile");
138 | profile().editBtn.tap();
139 | profile().textFieldWithLabel("Position").inputText("UI Tester");
140 | let cellPhone = "123";
141 | profile().textFieldWithLabel("Cellphone").inputText(cellPhone);
142 | profile().saveBtn.tap()
143 | profile().textWithLabel("Cellphone").verifyLabel(label: cellPhone);
144 | profile().backBtn.tap()
145 |
146 | //change device sync settings
147 | //Navigate to settings view
148 | settings().navigate("Device Sync Settings");
149 | settings().toggleSwitch(key: "Sync appointments")
150 | settings().toggleSwitch(key: "Sync opportunities")
151 | settings().toggleSwitch(key: "Sync reminders")
152 | settings().backBtn.tap()
153 |
154 | //change default reminder time
155 | //verify in activity form
156 | settings().navigate("Default Reminder Time");
157 | settings().tapRow("30 minutes before");
158 | settings().backBtn.tap()
159 |
160 | //logout
161 | self.logout()
162 | }
163 |
164 | func testEditContact() {
165 | self.loginAndGoToList(addressBook.ADDRESS_BOOK_LIST_NAME)
166 |
167 | //search and navigate to contact detail form
168 | utils().swipeDown()
169 | addressBook().searchAndGoToDetail("Contact A")
170 |
171 | //click call btn
172 | contactEdit().callBtn.tap()
173 | contactEdit().cellOnInfoPickerView("23456789").tap()
174 | // //check if activity with type call generated
175 | // utils().app.tables.element.swipeUp()
176 | // let callMsg = "Called 23456789."
177 | // contactEdit().verifyActivityDisplay(callMsg)
178 | // //click to open activity to check activity type
179 | // contactEdit().tapOnActivity(callMsg)
180 | // //verify activity type
181 | // callActivity().verifyType()
182 | // callActivity().backBtnOnEditView.tap()
183 | //
184 | // //swipe up to click email btn
185 | // utils().swipeDown()
186 | contactEdit().emailBtn.tap()
187 | let emailCell = contactEdit().cellOnInfoPickerView("a.contact@126.com")
188 | emailCell.verifyExists("Email btn existed");
189 | contactEdit().infoPickerCancelView.tap()
190 |
191 | //check status of locate btn
192 | contactEdit().locateBtn.verifyDisabled()
193 |
194 | //go to company cell
195 | let companyCell = contactEdit().cell("xd@xd.com")
196 | companyCell.verifyExists("Company exists")
197 | companyCell.tap()
198 | customerEdit().leftMenuBtn.tap()
199 |
200 | //edit contact information
201 | let firstNameStr = "FirstNAME"
202 | contactEdit().editContactInformation(firstName: firstNameStr)
203 | contactEdit().firstName.verifyLabel(label: firstNameStr, message: "Firstname not match \(firstNameStr)")
204 |
205 | //add address
206 | contact().swipeToAddAddress()
207 | contact().addAddressBtn.smartTap()
208 | let recipient = "ABC"
209 | let street1 = "Street1"
210 | let street2 = "Street2"
211 | let city = "City"
212 | let state = "Beijing"
213 | let zipCode = "0"
214 | let country = "China"
215 | let cellphone = "1"
216 | let telephone = "2"
217 | let type = "Test"
218 | address().createAddress(recipient: recipient, street1: street1, street2: street2, city: city, state: state, zipCode: zipCode, country: country, cellphone: cellphone, telephone: telephone, type: type)
219 | contact().cell(type).verifyExists("New address added.")
220 | //open this address
221 | contact().cell(type).tap()
222 | address().verifyDisplay(recipient: recipient, street1: street1, street2: street2, city: city, state: state, zipCode: zipCode, country: country, cellphone: cellphone, telephone: telephone, type: type)
223 | //edit address
224 | let newType = "NEW"
225 | address().editAddress(type: newType)
226 | contact().cell(newType).verifyExists("Address editted.")
227 |
228 | // utils().swipeUp()
229 | //
230 | // //add activity
231 | // contactEdit().addActivityBtn.tap()
232 | // let commentDetail = "COMMENT"
233 | // commentActivity().create(commentDetail)
234 | // contactEdit().verifyActivityDisplay(commentDetail)
235 |
236 | //swipe down for 5 times
237 | utils().swipeDown(time: 5);
238 |
239 | //edit contact details
240 | // contactEdit().editStatus("Inactive")
241 | // contactEdit().status.verifyLabel(label: "Inactive")
242 |
243 | contact().leftMenuBtn.tap()
244 | addressBook().leftMenuBtn.tap()
245 | //logout
246 | self.logout()
247 | }
248 |
249 | func testCreateContact() {
250 | self.loginAndGoToList(addressBook.ADDRESS_BOOK_LIST_NAME)
251 |
252 | //click create contact btn
253 | addressBook().createBtn.tap()
254 | addressBook().createContactBtn.tap()
255 |
256 | //cannot save, stay on this view
257 | contactCreate().rightMenuBtn.tap()
258 | contactCreate().lastName.verifyExists()
259 |
260 | //select company
261 | contactCreate().selectCompany("XD")
262 | contactCreate().cell("XD").verifyExists()
263 |
264 | //cannot save, stay on this view
265 | contactCreate().rightMenuBtn.tap()
266 | contactCreate().lastName.verifyExists()
267 |
268 | //create address
269 | contact().swipeToAddAddress()
270 | contactCreate().addAddressBtn.smartTap()
271 | address().createAddress(recipient: "AAA", street1: "1", street2: "2",state: "Beijing", country: "China")
272 |
273 | utils().swipeUp()
274 | contactCreate().cell("Beijing").verifyExists("New address created.")
275 |
276 | //edit address
277 | contactCreate().cell("Beijing").tap()
278 | address().editAddress(type: "CreateContact")
279 | utils().swipeUp()
280 | contactCreate().cell("CreateContact").verifyExists("Address editted.")
281 |
282 | utils().swipeDown()
283 | //input last name
284 | let newContactLastName = "LastName"
285 | contactCreate().lastName.inputText(newContactLastName)
286 | addressBook().cellWithTextField(newContactLastName).verifyExists()
287 |
288 | contactCreate().rightMenuBtn.tap()
289 | contactEdit().leftMenuBtn.tap()
290 |
291 | //click create btn
292 | self.logout()
293 | }
294 |
295 | func testEditCorporate() {
296 | self.loginAndGoToList(addressBook.ADDRESS_BOOK_LIST_NAME)
297 |
298 | //search and go to detail
299 | utils().swipeDown()
300 | addressBook().searchAndGoToDetail("XD")
301 |
302 | //click call btn
303 | customerEdit().callBtn.tap()
304 | customerEdit().cellOnInfoPickerView("123123").tap()
305 | //check if activity with type call generated
306 | customer().swipeToActivity()
307 | let msg = "Called 123123."
308 | customerEdit().cell(msg).verifyExists()
309 | //click to open activity to check activity type
310 | customerEdit().cell(msg).smartTap()
311 | //verify activity type
312 | callActivity().verifyType()
313 | callActivity().backBtnOnEditView.tap()
314 |
315 | customerEdit().emailBtn.tap()
316 | let emailCell = customerEdit().cellOnInfoPickerView("xd@xd.com")
317 | emailCell.verifyExists("Email btn existed");
318 | customerEdit().infoPickerCancelView.tap()
319 |
320 | //check status of locate btn
321 | customerEdit().locateBtn.verifyDisabled()
322 |
323 | //check main contact cell
324 | customerEdit().mainContactCell("Contact A").verifyExists()
325 | //navigate to main contact cell
326 | customerEdit().mainContactCell("Contact A").smartTap()
327 | contactEdit().leftMenuBtn.tap()
328 | //navigate to related contects list
329 | customerEdit().relatedContactsCell.tap()
330 | relatedContacts().contactCell("Contact B").tap()
331 | contactEdit().leftMenuBtn.tap()
332 | relatedContacts().leftMenuBtn.tap()
333 |
334 | //change main contact
335 | customerEdit().changeMainContactTo("Contact B")
336 | customerEdit().mainContactCell("Contact B").verifyExists()
337 |
338 | //edit contact information
339 | customerEdit().editCorporateContactInfo(name: "NEW_NAME")
340 | customerEdit().textWithLabel(customer.CORPORATE_NAME).verifyLabel(label: "NEW_NAME")
341 |
342 | customerEdit().swipeToAddress()
343 |
344 | //add address
345 | let addressType = "testEditCorporate"
346 | customerEdit().addAddressBtn.smartTap()
347 | address().createAddress(type: addressType)
348 | customerEdit().cell(addressType).verifyExists()
349 |
350 | //edit address
351 | customerEdit().cell(addressType).smartTap()
352 | let addressNewType = "testEditCorporate_new"
353 | address().editAddress(type: addressNewType)
354 | customerEdit().cell(addressNewType).verifyExists()
355 |
356 | //delete address
357 | customerEdit().swipeToAddress()
358 | customerEdit().deleteCell(addressNewType)
359 | customerEdit().cell(addressNewType).verifyNotExists()
360 |
361 | customerEdit().swipeToActivity()
362 |
363 | //add activity
364 | customerEdit().addActivityBtn.smartTap()
365 | let commentDetail = "COMMENT"
366 | commentActivity().create(commentDetail)
367 | customerEdit().cell(commentDetail).verifyExists()
368 |
369 | //edit activity
370 | customerEdit().cell(commentDetail).smartTap()
371 | let newCommentDetail = "newCommentDetail"
372 | commentActivity().edit(newCommentDetail)
373 | snapshot("Edit activity")
374 | customerEdit().cell(newCommentDetail).verifyExists()
375 |
376 | customerEdit().swipeToActivity()
377 |
378 | //delete activity
379 | customerEdit().deleteCell(newCommentDetail)
380 | customerEdit().cell(newCommentDetail).verifyNotExists()
381 |
382 | //create opportunity
383 | customerEdit().createOpportunity()
384 | opportunity().leftMenuBtn.tap()
385 |
386 | //edit details
387 | // customerEdit().editStatus("Inactive")
388 | // customerEdit().textWithLabel(customer.STATUS).verifyLabel(label: "Inactive")
389 |
390 | //back and logout
391 | customerEdit().leftMenuBtn.tap()
392 | addressBook().leftMenuBtn.tap()
393 | self.logout()
394 | }
395 |
396 | func testCreateCorporate() {
397 | self.loginAndGoToList(addressBook.ADDRESS_BOOK_LIST_NAME)
398 |
399 | //click create corporate btn
400 | addressBook().createBtn.tap()
401 | addressBook().createCorporateBtn.tap()
402 |
403 | //input corporate name
404 | let corproateName = "ACorporateName"
405 | customerCreate().corporateName.inputText(corproateName)
406 |
407 | //add address
408 | customerCreate().swipeToAddress()
409 | customerCreate().addAddressBtn.tap()
410 | let addressType = "testCreateCorporate"
411 | address().createAddress(type: addressType)
412 | customerCreate().cell(addressType).verifyExists()
413 |
414 | //edit address
415 | customerCreate().cell(addressType).tap()
416 | let addressNewType = "testCreateCorporate_new"
417 | address().editAddress(type: addressNewType)
418 | customerCreate().cell(addressNewType).verifyExists()
419 |
420 | //delete address
421 | customerCreate().deleteCell(addressNewType)
422 | customerCreate().cell(addressNewType).verifyNotExists()
423 |
424 | //click save btn
425 | customerCreate().rightMenuBtn.tap()
426 | //check go to edit form
427 | customerEdit().cell(corproateName).verifyExists()
428 |
429 | addressBook().cellWithText(corproateName).verifyExists()
430 |
431 | //logout
432 | addressBook().leftMenuBtn.tap()
433 | self.logout()
434 | }
435 |
436 | func testEditIndividual() {
437 | self.loginAndGoToList(addressBook.ADDRESS_BOOK_LIST_NAME)
438 |
439 | //search and go to detail
440 | utils().swipeDown()
441 | addressBook().searchAndGoToDetail("James Leung")
442 |
443 | //click call btn
444 | customerEdit().callBtn.tap()
445 | customerEdit().cellOnInfoPickerView("234567").tap()
446 | //check if activity with type call generated
447 | customerEdit().swipeToActivity()
448 | let msg = "Called 234567."
449 | customerEdit().cell(msg).verifyExists()
450 | //click to open activity to check activity type
451 | customerEdit().cell(msg).tap()
452 | //verify activity type
453 | callActivity().verifyType()
454 | callActivity().backBtnOnEditView.tap()
455 |
456 | //swipe up to click email btn
457 | customerEdit().emailBtn.tap()
458 | let emailCell = customerEdit().cellOnInfoPickerView("test@126.com")
459 | emailCell.verifyExists("Email btn existed");
460 | customerEdit().infoPickerCancelView.tap()
461 |
462 | //click locate btn
463 | customerEdit().locateBtn.tap()
464 | customerEdit().infoPickerCancelView.tap()
465 |
466 | utils().swipeDown(time: 8)
467 | //edit contact information
468 | let lastName = "NEW_NAME"
469 | customerEdit().editIndividualGeneralInfo(lastName: lastName)
470 | customerEdit().textWithLabel(customer.LAST_NAME).verifyLabel(label: lastName)
471 |
472 | customerEdit().swipeToAddress()
473 |
474 | //verify existed address
475 | customerEdit().cell("chenhui road 1001").verifyExists()
476 | //add address
477 | let addressType = "testEditIndividual"
478 | customerEdit().addAddressBtn.smartTap()
479 | address().createAddress(type: addressType)
480 | customerEdit().cell(addressType).verifyExists()
481 |
482 | //edit address
483 | sleep(1)
484 | customerEdit().cell(addressType).tap()
485 | snapshot("TapOnAddress")
486 | let addressNewType = "testEditIndividual_new"
487 | address().editAddress(type: addressNewType)
488 | customerEdit().cell(addressNewType).verifyExists()
489 |
490 | customerEdit().swipeToAddress()
491 | //delete address
492 | customerEdit().deleteCell(addressNewType)
493 | customerEdit().cell(addressNewType).verifyNotExists()
494 |
495 | customerEdit().swipeToActivity()
496 |
497 | //add activity
498 | customerEdit().addActivityBtn.tap()
499 | let commentDetail = "COMMENT"
500 | commentActivity().create(commentDetail)
501 | customerEdit().cell(commentDetail).verifyExists()
502 |
503 | //edit activity
504 | customerEdit().cell(commentDetail).tap()
505 | let newCommentDetail = "newCommentDetail"
506 | commentActivity().edit(newCommentDetail)
507 | customerEdit().cell(newCommentDetail).verifyExists()
508 |
509 | customerEdit().swipeToActivity()
510 | //delete activity
511 | customerEdit().deleteCell(newCommentDetail)
512 | customerEdit().cell(newCommentDetail).verifyNotExists()
513 |
514 | //create opportunity
515 | customerEdit().createOpportunity()
516 | opportunity().leftMenuBtn.tap()
517 |
518 | utils().swipeDown(time:8)
519 | //edit details
520 | customerEdit().editStatus("Inactive")
521 | utils().swipeUp()
522 | customerEdit().status.verifyLabel(label: "Inactive")
523 |
524 | //back and logout
525 | customerEdit().leftMenuBtn.tap()
526 | addressBook().leftMenuBtn.tap()
527 | self.logout()
528 | }
529 |
530 | func testCreateIndividual() {
531 | self.loginAndGoToList(addressBook.ADDRESS_BOOK_LIST_NAME)
532 |
533 | //click create corporate btn
534 | addressBook().createBtn.tap()
535 | addressBook().createIndividualBtn.tap()
536 |
537 | //input corporate name
538 | let lastName = "ALastName"
539 | customerCreate().textFieldWithLabel(customer.LAST_NAME).inputText(lastName)
540 |
541 | customerCreate().swipeToAddress()
542 | //add address
543 | customerCreate().addAddressBtn.tap()
544 | //add address
545 | let addressType = "testCreateIndividual"
546 | address().createAddress(type: addressType)
547 | utils().swipeUp()
548 | customerCreate().cell(addressType).verifyExists()
549 |
550 | //edit address
551 | customerCreate().cell(addressType).tap()
552 | let addressNewType = "testCreateIndividual_new"
553 | address().editAddress(type: addressNewType)
554 | utils().swipeUp()
555 | customerCreate().cell(addressNewType).verifyExists()
556 |
557 | //delete address
558 | customerCreate().deleteCell(addressNewType)
559 | customerCreate().cell(addressNewType).verifyNotExists()
560 |
561 | //click save btn
562 | customerCreate().rightMenuBtn.tap()
563 | addressBook().cellWithText(lastName).verifyExists()
564 |
565 | //logout
566 | addressBook().leftMenuBtn.tap()
567 | self.logout()
568 | }
569 |
570 | func testHomeCards() {
571 | self.loginAndGoToList("");
572 |
573 | //verify card
574 | home().verifyCardExisting("Opportunity Due");
575 | home().verifyCardExisting("Your Current Pipeline");
576 |
577 | //logout
578 | siderBar().homeMenuBtnInHome.forceTap();
579 | self.logout();
580 | }
581 |
582 | func testProductList() {
583 | self.loginAndGoToList("Products");
584 |
585 | //play filter
586 | productList().clickFilterBtn();
587 | productFilter().apply("MyCategory", "MyBrand", ["0","100"]);
588 | productList().verifyProductExisting("MyCategory", false); //doesn't existing
589 |
590 | productList().clickFilterBtn();
591 | productFilter().apply(nil, nil, ["1","86"]); // 1 to 10086
592 | productList().verifyProductExisting("MyCategory", true);
593 | productList().goToDetailedView("abc"); //product name abc
594 |
595 | //verify product
596 | product().waitForViewDisplays(self, "abc"); //abc is title
597 | product().verifyCellValue("Product Category", "MyCategory");
598 | utils().swipeUp()
599 | product().verifyCellValue("Brand", "MyBrand");
600 |
601 | //logout
602 | productList().leftMenuBtn.tap();
603 | self.logout();
604 | }
605 |
606 | func testLeadsList() {
607 | self.loginAndGoToList("Leads")
608 |
609 | //filter and sort
610 | leadsList().filterBtn.tap()
611 | leadsFilter().applyFilter(owner: "All", statuses: ["Qualified", "Unqualified"], qualification: "Hot")
612 | leadsList().filterBtn.tap()
613 | leadsFilter().sortTabBtn.tap()
614 | leadsFilter().sortTable.cells.element(boundBy: 1).tap()
615 | leadsList().cellWithText("D C").tap()
616 |
617 | lead().leftMenuBtn.tap()
618 |
619 | //search
620 | leadsList().searchAndGoToDetail("James Leung");
621 |
622 | lead().cell("James Leung").verifyExists()
623 | }
624 |
625 | func testEditLead() {
626 | self.loginAndGoToList("Leads")
627 |
628 | leadsList().newQuickFilterBtn.tap()
629 |
630 | leadsList().cellWithText("A B").tap()
631 |
632 | //check header action btn
633 | lead().contactCall.tap()
634 | lead().cellOnInfoPickerView("Cellphone").tap()
635 | //check if activity with type call generated
636 | lead().swipeToActivity()
637 | let msg = "Called"
638 | lead().cell(msg).verifyExists()
639 | //click to open activity to check activity type
640 | lead().cell(msg).smartTap()
641 | //verify activity type
642 | callActivity().verifyType()
643 | callActivity().backBtnOnEditView.tap()
644 |
645 | lead().contactEmail.tap()
646 | lead().cellOnInfoPickerView("a@nelson.com").verifyExists()
647 | lead().infoPickerCancelView.tap()
648 |
649 | //click locate btn
650 | lead().contactLocate.verifyDisabled()
651 |
652 | //change status
653 | lead().changeStatus("In Process")
654 | lead().status.verifyLabel(label: "In Process")
655 |
656 | lead().descriptionField.inputText("New Lead Description")
657 |
658 | let newQualification = "Cold"
659 | let newRemark = "Edit Lead Remark"
660 | lead().editGeneralInfo(qualification: newQualification, remarks: newRemark)
661 | lead().textWithLabel(lead.QUALIFICATION).verifyLabel(label: newQualification)
662 | lead().textWithLabel(lead.REMARKS).verifyLabel(label: newRemark)
663 |
664 | utils().swipeUp()
665 | let newPhone = "1"
666 | let newEmail = "2@test.com"
667 | lead().editContactInfo(phone: newPhone, email: newEmail)
668 | lead().textWithLabel(lead.PHONE).verifyLabel(label: newPhone)
669 | lead().textWithLabel(lead.EMAIL).verifyLabel(label: newEmail)
670 |
671 | utils().swipeUpUntilElementVisible(element: lead().addAddressBtn)
672 | //create address
673 | lead().addAddressBtn.smartTap()
674 | let newAddress = "street1"
675 | address().createAddress(street1: newAddress)
676 | lead().cell(newAddress).verifyExists()
677 | lead().addAddressBtn.verifyNotExists()
678 | //edit address
679 | lead().cell(newAddress).tap()
680 | let editAddress = "edit_street1"
681 | address().editAddress(street1: editAddress)
682 | lead().cell(editAddress).verifyExists()
683 | //delete address
684 | lead().deleteCell(newAddress)
685 | lead().addAddressBtn.verifyExists()
686 |
687 | utils().swipeUpUntilElementVisible(element: lead().addActivityBtn)
688 | //add activity
689 | lead().addActivityBtn.smartTap()
690 | let commentDetail = "COMMENT"
691 | commentActivity().create(commentDetail)
692 | lead().cell(commentDetail).verifyExists()
693 | //edit activity
694 | lead().cell(commentDetail).tap()
695 | let newCommentDetail = "newCommentDetail"
696 | commentActivity().edit(newCommentDetail)
697 | lead().cell(newCommentDetail).verifyExists()
698 | //delete activity
699 | lead().deleteCell(newCommentDetail)
700 | lead().cell(newCommentDetail).verifyNotExists()
701 |
702 | //convert to customer
703 | lead().rightMenuBtn.tap()
704 | lead().buttonWithText("Cancel").tap()
705 | lead().changeStatus("Copied")
706 | customerEdit().leftMenuBtn.tap()
707 |
708 | lead().leftMenuBtn.tap()
709 | leadsList().leftMenuBtn.tap()
710 | self.logout()
711 | }
712 |
713 | func testCreateLead() {
714 | self.loginAndGoToList("Leads")
715 |
716 | leadsList().createBtn.tap()
717 |
718 | let newDesc = "Create Lead"
719 | lead().descriptionField.inputText(newDesc)
720 | var newPhone = "a"
721 | var newEmail = "1"
722 | lead().textFieldWithLabel(lead.PHONE).inputText(newPhone)
723 | lead().textFieldWithLabel(lead.EMAIL).inputText(newEmail)
724 | lead().rightMenuBtn.tap()
725 | newPhone = "1"
726 | newEmail = "1@126.com"
727 | lead().textFieldWithLabel(lead.PHONE).inputText(newPhone)
728 | lead().textFieldWithLabel(lead.EMAIL).inputText(newEmail)
729 |
730 | lead().rightMenuBtn.tap()
731 |
732 | leadsList().cellWithText(newEmail).verifyExists()
733 |
734 | leadsList().leftMenuBtn.tap()
735 | self.logout()
736 |
737 | }
738 |
739 | func testReports() {
740 | self.loginAndGoToList("Reports")
741 |
742 | reportsList().navigate("Pipeline Overview")
743 |
744 | overview().setFilter("Weighted", "Weighted amount")
745 | overview().setFilter("Mine", "My opportunities")
746 |
747 | reportsList().backBtn.tap()
748 |
749 | reportsList().navigate("Opportunities Outlook")
750 |
751 | outlook().setFilter("Weighted", "Potential amount")
752 | outlook().setFilter("Weekly", "Monthly")
753 | outlook().setFilter("Mine", "All opportunities")
754 |
755 | reportsList().backBtn.tap()
756 |
757 | reportsList().navigate("Sales Summary")
758 |
759 | summary().pullDownMenu("Channels(3)")
760 | summary().multiSelect("Unselect All", ["Central_Park", "默认渠道"])
761 | summary().applyBtn.tap()
762 |
763 | summary().setFilter("Weekly", "Monthly")
764 | summary().setFilter("Mine", "My Sales Orders")
765 |
766 | reportsList().backBtn.tap()
767 |
768 | self.logout()
769 | }
770 |
771 | func testSalesOrders() {
772 | self.loginAndGoToList("Sales Orders")
773 |
774 | salesOrdersList().filterBtn.tap()
775 | salesOrdersFilter().applyFilter(owner: "All", customerTypes: ["Individual", "Corporate"])
776 |
777 | salesOrders().goToDetailedView("21") //product name 21
778 | salesOrders().navigate("Amount")
779 | utils().swipeDown()
780 | utils().swipeUp()
781 |
782 | //click call btn
783 | salesOrders().callBtn.tap()
784 | salesOrders().cellOnInfoPickerView("234567").tap()
785 |
786 | //click email btn
787 | salesOrders().emailBtn.tap()
788 | salesOrders().cellOnInfoPickerView("test@126.com").tap()
789 |
790 | //click locate btn
791 | salesOrders().locateBtn.tap()
792 | salesOrders().infoPickerCancelView.tap()
793 | salesOrdersList().backBtn.tap()
794 |
795 | salesOrdersList().filterBtn.tap()
796 | salesOrdersFilter().sortTabBtn.tap()
797 | salesOrdersFilter().sortTable.cells.element(boundBy: 1).tap()
798 |
799 | self.logout()
800 | }
801 | }
802 |
--------------------------------------------------------------------------------
/utilis/SnapshotHelper.swift:
--------------------------------------------------------------------------------
1 | //
2 | // SnapshotHelper.swift
3 | // Example
4 | //
5 |
6 | //
7 |
8 | import Foundation
9 | import XCTest
10 |
11 | var deviceLanguage = "en-US"
12 | var locale = "en-US"
13 | var index = 1
14 |
15 | @available(*, deprecated, message: "use setupSnapshot: instead")
16 | func setLanguage(_ app: XCUIApplication) {
17 | setupSnapshot(app)
18 | }
19 |
20 | func setupSnapshot(_ app: XCUIApplication) {
21 | Snapshot.setupSnapshot(app)
22 | }
23 |
24 | func snapshot(_ name: String, waitForLoadingIndicator: Bool = true) {
25 | let indexName:String
26 | if index < 10 {
27 | indexName = "0\(index)_\(name)"
28 | }else{
29 | indexName = "\(index)_\(name)"
30 | }
31 | index += 1
32 | Snapshot.snapshot(indexName, waitForLoadingIndicator: waitForLoadingIndicator)
33 | }
34 |
35 | open class Snapshot: NSObject {
36 |
37 | open class func setupSnapshot(_ app: XCUIApplication) {
38 | setLanguage(app)
39 | setLocale(app)
40 | setLaunchArguments(app)
41 | }
42 |
43 | class func setLanguage(_ app: XCUIApplication) {
44 | guard let prefix = pathPrefix() else {
45 | return
46 | }
47 |
48 | let path = prefix.appendingPathComponent("language.txt")
49 |
50 | do {
51 | let trimCharacterSet = CharacterSet.whitespacesAndNewlines
52 | deviceLanguage = try NSString(contentsOfFile: path, encoding: String.Encoding.utf8.rawValue).trimmingCharacters(in: trimCharacterSet) as String
53 | app.launchArguments += ["-AppleLanguages", "(\(deviceLanguage))"]
54 | } catch {
55 | print("Couldn't detect/set language...")
56 | }
57 | }
58 |
59 | class func setLocale(_ app: XCUIApplication) {
60 | guard let prefix = pathPrefix() else {
61 | return
62 | }
63 |
64 | let path = prefix.appendingPathComponent("locale.txt")
65 |
66 | do {
67 | let trimCharacterSet = CharacterSet.whitespacesAndNewlines
68 | locale = try NSString(contentsOfFile: path, encoding: String.Encoding.utf8.rawValue).trimmingCharacters(in: trimCharacterSet) as String
69 | } catch {
70 | print("Couldn't detect/set locale...")
71 | }
72 | if locale.isEmpty {
73 | locale = Locale(identifier: deviceLanguage).identifier
74 | }
75 | app.launchArguments += ["-AppleLocale", "\"\(locale)\""]
76 | }
77 |
78 | class func setLaunchArguments(_ app: XCUIApplication) {
79 | guard let prefix = pathPrefix() else {
80 | return
81 | }
82 |
83 | let path = prefix.appendingPathComponent("snapshot-launch_arguments.txt")
84 | app.launchArguments += ["-FASTLANE_SNAPSHOT", "YES", "-ui_testing"]
85 |
86 | do {
87 | let launchArguments = try NSString(contentsOfFile: path, encoding: String.Encoding.utf8.rawValue) as String
88 | let regex = try NSRegularExpression(pattern: "(\\\".+?\\\"|\\S+)", options: [])
89 | let matches = regex.matches(in: launchArguments, options: [], range: NSRange(location:0, length:launchArguments.characters.count))
90 | let results = matches.map { result -> String in
91 | (launchArguments as NSString).substring(with: result.range)
92 | }
93 | app.launchArguments += results
94 | } catch {
95 | print("Couldn't detect/set launch_arguments...")
96 | }
97 | }
98 |
99 | open class func snapshot(_ name: String, waitForLoadingIndicator: Bool = true) {
100 | if waitForLoadingIndicator {
101 | waitForLoadingIndicatorToDisappear()
102 | }
103 |
104 | print("snapshot: \(name)") // more information about this, check out https://github.com/fastlane/fastlane/tree/master/snapshot#how-does-it-work
105 |
106 | sleep(1) // Waiting for the animation to be finished (kind of)
107 |
108 | #if os(tvOS)
109 | XCUIApplication().childrenMatchingType(.Browser).count
110 | #else
111 | XCUIDevice.shared().orientation = .unknown
112 | #endif
113 | }
114 |
115 | class func waitForLoadingIndicatorToDisappear() {
116 | #if os(tvOS)
117 | return
118 | #endif
119 |
120 | let query = XCUIApplication().statusBars.children(matching: .other).element(boundBy: 1).children(matching: .other)
121 |
122 | while (0.. NSString? {
129 | if let path = ProcessInfo().environment["SIMULATOR_HOST_HOME"] as NSString? {
130 | return path.appendingPathComponent("Library/Caches/tools.fastlane") as NSString?
131 | }
132 | print("Couldn't find Snapshot configuration files at ~/Library/Caches/tools.fastlane")
133 | return nil
134 | }
135 | }
136 |
137 | extension XCUIElement {
138 | var isLoadingIndicator: Bool {
139 | return self.frame.size == CGSize(width: 10, height: 20)
140 | }
141 | }
142 |
143 | // Please don't remove the lines below
144 | // They are used to detect outdated configuration files
145 | // SnapshotHelperVersion [1.2]
146 |
--------------------------------------------------------------------------------
/utilis/XCUIElement+ext.swift:
--------------------------------------------------------------------------------
1 | //
2 | // XCUIElement+ext.swift
3 | // anwstream
4 | //
5 | //
6 | //
7 |
8 | import Foundation
9 | import XCTest
10 |
11 | extension XCUIElement {
12 | func scrollUpToElement(element: XCUIElement) {
13 | while !element.visible() {
14 | swipeUp()
15 | }
16 | }
17 |
18 | func scrollDownToElement(element: XCUIElement) {
19 | while !element.visible() {
20 | swipeDown()
21 | }
22 | }
23 |
24 | func visible() -> Bool {
25 | guard self.exists && !self.frame.isEmpty && self.isHittable else { return false }
26 | return XCUIApplication().windows.element(boundBy: 0).frame.contains(self.frame)
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/utilis/utils.swift:
--------------------------------------------------------------------------------
1 | //
2 | // utils.swift
3 | // anwstream
4 | //
5 | // Created by Lu, Luis on 07/11/2016.
6 | //
7 | //
8 |
9 | import Foundation
10 | import XCTest
11 |
12 | class utils: NSObject{
13 |
14 |
15 | let app = XCUIApplication()
16 |
17 | /**
18 | - parameter dateElement: locate dateTime element
19 | - parameter dateTime: match specified format like Dec 12-10-10-PM
20 | */
21 | func handleDateTimePicker(_ dateElement:XCUIElement, dateTime:String) {
22 | dateElement.tap()
23 | let dateTimeArray = dateTime.components(separatedBy: "-")
24 | app.pickerWheels.element(boundBy: 0).adjust(toPickerWheelValue: dateTimeArray[0])
25 | app.pickerWheels.element(boundBy: 1).adjust(toPickerWheelValue: dateTimeArray[1])
26 | app.pickerWheels.element(boundBy: 2).adjust(toPickerWheelValue: dateTimeArray[2])
27 | app.pickerWheels.element(boundBy: 3).adjust(toPickerWheelValue: dateTimeArray[3])
28 | app.toolbars.buttons.element(boundBy: 0).tap()
29 | }
30 |
31 |
32 |
33 | /**
34 | - parameter dateElement: locate dateTime element
35 | - parameter date: match specified format like December-12-2018
36 | */
37 | func handleDatePicker(_ dateElement:XCUIElement, date:String) {
38 | dateElement.tap()
39 | let dateArray = date.components(separatedBy: "-")
40 | app.pickerWheels.element(boundBy: 0).adjust(toPickerWheelValue: dateArray[0])
41 | app.pickerWheels.element(boundBy: 1).adjust(toPickerWheelValue: dateArray[1])
42 | app.pickerWheels.element(boundBy: 2).adjust(toPickerWheelValue: dateArray[2])
43 | app.toolbars.buttons.element(boundBy: 0).tap()
44 | }
45 |
46 | func handleSelectorPicker(_ identifier:String) {
47 | app.pickerWheels.element.adjust(toPickerWheelValue: identifier)
48 | app.toolbars.buttons.element(boundBy: 0).tap()
49 | }
50 |
51 | func handleKeyboard(_ key:String){
52 | if app.keyboards.buttons[key].exists {
53 | app.keyboards.buttons[key].tap()
54 | } else if app.keyboards.keys[key].exists {
55 | app.keyboards.keys[key].tap()
56 | } else {
57 | app.toolbars.buttons["Done"].tap()
58 | }
59 | }
60 |
61 | // func handleAlert(_ actionIdentifier:String){
62 | // let actionElement = app.alerts.buttons[actionIdentifier]
63 | // actionElement.tap()
64 | // }
65 |
66 | // func handleSystemAlert(_ xcTestCase:XCTestCase, _ actionIdentifier:String){
67 | // let monitorToken = xcTestCase.addUIInterruptionMonitor(withDescription: "Calender permission") { (alert) -> Bool in
68 | // alert.buttons[actionIdentifier].tap()
69 | // return true
70 | // }
71 | // app.tap() // need to interact with the app for the handler to fire
72 | // }
73 |
74 | // func verifyElementExists(_ element: XCUIElement, message: String = "Can not find related element"){
75 | //// XCTAssert(element.exists,message)
76 | // element.verifyExists(message)
77 | // }
78 | //
79 | // func verifyElementDisappers(_ element: XCUIElement, message: String = "Related element still appears"){
80 | // XCTAssertTrue(!element.exists, message)
81 | // }
82 |
83 | func waitForElementToAppear(_ xcTestCase:XCTestCase, _ element: XCUIElement, timeout : Double = 5) {
84 | let existsPredicate = NSPredicate(format: "exists == true")
85 | xcTestCase.expectation(for: existsPredicate, evaluatedWith: element, handler: nil)
86 | xcTestCase.waitForExpectations(timeout: timeout) { (error) -> Void in
87 | XCTAssert(error == nil, "Failed to find \(element) after \(timeout) seconds.")
88 | }
89 | }
90 | // func waitForElementToAppear(_ element: XCUIElement, timeout : Double = 5, file: String = #file, line: UInt = #line) {
91 | // let existsPredicate = NSPredicate(format: "exists == true")
92 | // expectation(for: existsPredicate, evaluatedWith: element, handler: nil)
93 | // waitForExpectations(timeout: timeout) { (error) -> Void in
94 | // if (error != nil) {
95 | // let message = "Failed to find \(element) after \(timeout) seconds."
96 | // self.recordFailure(withDescription: message, inFile: file, atLine: line, expected: true)
97 | // }
98 | // }
99 | // }
100 |
101 | func swipeUp() {
102 | self.app.tables.element(boundBy: 0).swipeUp()
103 | }
104 |
105 | func swipeUpUntilElementVisible(element: XCUIElement) {
106 | self.app.tables.element(boundBy: 0).scrollUpToElement(element: element)
107 | }
108 |
109 | func swipeDown() {
110 | self.app.tables.element(boundBy: 0).swipeDown()
111 | }
112 |
113 | func swipeDownUntilElementVisible(element: XCUIElement) {
114 | self.app.tables.element(boundBy: 0).scrollDownToElement(element: element)
115 | }
116 |
117 | func swipeDown(time: Int){
118 | for _ in 0 ..< time {
119 | utils().swipeDown()
120 | }
121 | }
122 | }
123 |
124 |
125 |
--------------------------------------------------------------------------------