@@ -24,6 +24,10 @@ const TheiaSettingsViewData = {
2424} ;
2525
2626export const PreferenceIds = {
27+ Editor : {
28+ AutoSave : 'editor.autoSave' ,
29+ RenderWhitespace : 'editor.renderWhitespace'
30+ } ,
2731 Explorer : {
2832 AutoReveal : 'explorer.autoReveal'
2933 } ,
@@ -33,6 +37,19 @@ export const PreferenceIds = {
3337} ;
3438
3539export const DefaultPreferences = {
40+ Editor : {
41+ AutoSave : {
42+ On : 'on' ,
43+ Off : 'off'
44+ } ,
45+ RenderWhitespace : {
46+ None : 'none' ,
47+ Boundary : 'boundary' ,
48+ Selection : 'selection' ,
49+ Trailing : 'trailing' ,
50+ All : 'all'
51+ }
52+ } ,
3653 Explorer : {
3754 AutoReveal : {
3855 Enabled : true
@@ -50,6 +67,7 @@ export enum TheiaPreferenceScope {
5067
5168export class TheiaPreferenceView extends TheiaView {
5269 public customTimeout ?: number ;
70+ protected modificationIndicator = '.theia-mod-item-modified' ;
5371
5472 constructor ( app : TheiaApp ) {
5573 super ( TheiaSettingsViewData , app ) ;
@@ -72,98 +90,81 @@ export class TheiaPreferenceView extends TheiaView {
7290 await scopeTab . click ( ) ;
7391 }
7492
93+ async getBooleanPreferenceByPath ( sectionTitle : string , name : string ) : Promise < boolean > {
94+ const preferenceId = await this . findPreferenceId ( sectionTitle , name ) ;
95+ return this . getBooleanPreferenceById ( preferenceId ) ;
96+ }
97+
7598 async getBooleanPreferenceById ( preferenceId : string ) : Promise < boolean > {
7699 const element = await this . findPreferenceEditorById ( preferenceId ) ;
77100 return element . isChecked ( ) ;
78101 }
79102
80- async getBooleanPreferenceByPath ( sectionTitle : string , name : string ) : Promise < boolean > {
103+ async setBooleanPreferenceByPath ( sectionTitle : string , name : string , value : boolean ) : Promise < void > {
81104 const preferenceId = await this . findPreferenceId ( sectionTitle , name ) ;
82- return this . getBooleanPreferenceById ( preferenceId ) ;
105+ return this . setBooleanPreferenceById ( preferenceId , value ) ;
83106 }
84107
85108 async setBooleanPreferenceById ( preferenceId : string , value : boolean ) : Promise < void > {
86109 const element = await this . findPreferenceEditorById ( preferenceId ) ;
87110 return value ? element . check ( ) : element . uncheck ( ) ;
88111 }
89112
90- async setBooleanPreferenceByPath ( sectionTitle : string , name : string , value : boolean ) : Promise < void > {
113+ async getStringPreferenceByPath ( sectionTitle : string , name : string ) : Promise < string > {
91114 const preferenceId = await this . findPreferenceId ( sectionTitle , name ) ;
92- return this . setBooleanPreferenceById ( preferenceId , value ) ;
115+ return this . getStringPreferenceById ( preferenceId ) ;
93116 }
94117
95118 async getStringPreferenceById ( preferenceId : string ) : Promise < string > {
96119 const element = await this . findPreferenceEditorById ( preferenceId ) ;
97120 return element . evaluate ( e => ( e as HTMLInputElement ) . value ) ;
98121 }
99122
100- async getStringPreferenceByPath ( sectionTitle : string , name : string ) : Promise < string > {
123+ async setStringPreferenceByPath ( sectionTitle : string , name : string , value : string ) : Promise < void > {
101124 const preferenceId = await this . findPreferenceId ( sectionTitle , name ) ;
102- return this . getStringPreferenceById ( preferenceId ) ;
125+ return this . setStringPreferenceById ( preferenceId , value ) ;
103126 }
104127
105128 async setStringPreferenceById ( preferenceId : string , value : string ) : Promise < void > {
106129 const element = await this . findPreferenceEditorById ( preferenceId ) ;
107130 return element . fill ( value ) ;
108131 }
109132
110- async setStringPreferenceByPath ( sectionTitle : string , name : string , value : string ) : Promise < void > {
133+ async getOptionsPreferenceByPath ( sectionTitle : string , name : string ) : Promise < string > {
111134 const preferenceId = await this . findPreferenceId ( sectionTitle , name ) ;
112- return this . setStringPreferenceById ( preferenceId , value ) ;
135+ return this . getOptionsPreferenceById ( preferenceId ) ;
113136 }
114137
115- async waitForModified ( preferenceId : string ) : Promise < void > {
116- await this . activate ( ) ;
117- const viewElement = await this . viewElement ( ) ;
118- await viewElement ?. waitForSelector ( `${ this . getPreferenceGutterSelector ( preferenceId ) } .theia-mod-item-modified` , { timeout : this . customTimeout } ) ;
138+ async getOptionsPreferenceById ( preferenceId : string ) : Promise < string > {
139+ const element = await this . findPreferenceEditorById ( preferenceId , 'select' ) ;
140+ return element . evaluate ( e => {
141+ const selectElement = ( e as HTMLSelectElement ) ;
142+ const option = selectElement . options [ selectElement . selectedIndex ] ;
143+ return option . text ;
144+ } ) ;
119145 }
120146
121- async resetStringPreferenceById ( preferenceId : string ) : Promise < void > {
122- const resetPreferenceButton = await this . findPreferenceResetButton ( preferenceId ) ;
123- if ( ! resetPreferenceButton ) {
124- // preference not modified
125- return ;
126- }
127- const previousValue = await this . getStringPreferenceById ( preferenceId ) ;
128- const selector = this . getPreferenceEditorSelector ( preferenceId ) ;
129- const done = await resetPreferenceButton . click ( ) ;
130- await this . page . waitForFunction ( data => {
131- const element = document . querySelector ( data . selector ) ;
132- if ( ! element ) {
133- throw new Error ( `Could not find preference element with id "${ data . preferenceId } "` ) ;
134- }
135- const value = ( element as HTMLInputElement ) . value ;
136- return value !== data . previousValue ;
137- } , { preferenceId, selector, previousValue, done } , { timeout : this . customTimeout } ) ;
138- }
139-
140- async resetStringPreferenceByPath ( sectionTitle : string , name : string ) : Promise < void > {
147+ async setOptionsPreferenceByPath ( sectionTitle : string , name : string , value : string ) : Promise < void > {
141148 const preferenceId = await this . findPreferenceId ( sectionTitle , name ) ;
142- return this . resetStringPreferenceById ( preferenceId ) ;
149+ return this . setOptionsPreferenceById ( preferenceId , value ) ;
143150 }
144151
145- async resetBooleanPreferenceById ( preferenceId : string ) : Promise < void > {
146- const resetPreferenceButton = await this . findPreferenceResetButton ( preferenceId ) ;
147- if ( ! resetPreferenceButton ) {
148- // preference not modified
149- return ;
150- }
151- const previousValue = await this . getBooleanPreferenceById ( preferenceId ) ;
152- const selector = this . getPreferenceEditorSelector ( preferenceId ) ;
153- const done = await resetPreferenceButton . click ( ) ;
154- await this . page . waitForFunction ( data => {
155- const element = document . querySelector ( data . selector ) ;
156- if ( ! element ) {
157- throw new Error ( `Could not find preference element with id "${ data . preferenceId } "` ) ;
158- }
159- const value = ( element as HTMLInputElement ) . checked ;
160- return value !== data . previousValue ;
161- } , { preferenceId, selector, previousValue, done } , { timeout : this . customTimeout } ) ;
162- }
163-
164- async resetBooleanPreferenceByPath ( sectionTitle : string , name : string ) : Promise < void > {
152+ async setOptionsPreferenceById ( preferenceId : string , value : string ) : Promise < void > {
153+ const element = await this . findPreferenceEditorById ( preferenceId , 'select' ) ;
154+ await element . selectOption ( { label : value } ) ;
155+ }
156+
157+ async resetPreferenceByPath ( sectionTitle : string , name : string ) : Promise < void > {
165158 const preferenceId = await this . findPreferenceId ( sectionTitle , name ) ;
166- return this . resetBooleanPreferenceById ( preferenceId ) ;
159+ return this . resetPreferenceById ( preferenceId ) ;
160+ }
161+
162+ async resetPreferenceById ( preferenceId : string ) : Promise < void > {
163+ // this is just to fail if the preference doesn't exist at all
164+ await this . findPreferenceEditorById ( preferenceId , '' ) ;
165+ const resetPreferenceButton = await this . findPreferenceResetButton ( preferenceId ) ;
166+ await resetPreferenceButton . click ( ) ;
167+ await this . waitForUnmodified ( preferenceId ) ;
167168 }
168169
169170 private async findPreferenceId ( sectionTitle : string , name : string ) : Promise < string > {
@@ -178,9 +179,9 @@ export class TheiaPreferenceView extends TheiaView {
178179 return preferenceId ;
179180 }
180181
181- private async findPreferenceEditorById ( preferenceId : string ) : Promise < ElementHandle < SVGElement | HTMLElement > > {
182+ private async findPreferenceEditorById ( preferenceId : string , elementType : string = 'input' ) : Promise < ElementHandle < SVGElement | HTMLElement > > {
182183 const viewElement = await this . viewElement ( ) ;
183- const element = await viewElement ?. waitForSelector ( this . getPreferenceEditorSelector ( preferenceId ) , { timeout : this . customTimeout } ) ;
184+ const element = await viewElement ?. waitForSelector ( this . getPreferenceEditorSelector ( preferenceId , elementType ) , { timeout : this . customTimeout } ) ;
184185 if ( ! element ) {
185186 throw new Error ( `Could not find element with preference id "${ preferenceId } "` ) ;
186187 }
@@ -191,26 +192,13 @@ export class TheiaPreferenceView extends TheiaView {
191192 return `li[data-pref-id="${ preferenceId } "]` ;
192193 }
193194
194- private getPreferenceEditorSelector ( preferenceId : string ) : string {
195- return `${ this . getPreferenceSelector ( preferenceId ) } input ` ;
195+ private getPreferenceEditorSelector ( preferenceId : string , elementType : string ) : string {
196+ return `${ this . getPreferenceSelector ( preferenceId ) } ${ elementType } ` ;
196197 }
197198
198- private getPreferenceGutterSelector ( preferenceId : string ) : string {
199- return `${ this . getPreferenceSelector ( preferenceId ) } .pref-context-gutter` ;
200- }
201-
202- private async findPreferenceResetButton ( preferenceId : string ) : Promise < ElementHandle < SVGElement | HTMLElement > | undefined > {
199+ private async findPreferenceResetButton ( preferenceId : string ) : Promise < ElementHandle < SVGElement | HTMLElement > > {
203200 await this . activate ( ) ;
204201 const viewElement = await this . viewElement ( ) ;
205- const gutter = await viewElement ?. waitForSelector ( `${ this . getPreferenceGutterSelector ( preferenceId ) } ` , { timeout : this . customTimeout } ) ;
206- if ( ! gutter ) {
207- throw new Error ( `Could not determine modified state for element with preference id "${ preferenceId } "` ) ;
208- }
209- const isModified = await gutter . evaluate ( e => e . classList . contains ( 'theia-mod-item-modified' ) ) ;
210- if ( ! isModified ) {
211- return undefined ;
212- }
213-
214202 const settingsContextMenuBtn = await viewElement ?. waitForSelector ( `${ this . getPreferenceSelector ( preferenceId ) } .settings-context-menu-btn` ) ;
215203 if ( ! settingsContextMenuBtn ) {
216204 throw new Error ( `Could not find context menu button for element with preference id "${ preferenceId } "` ) ;
@@ -223,4 +211,19 @@ export class TheiaPreferenceView extends TheiaView {
223211 return resetPreferenceButton ;
224212 }
225213
214+ async waitForModified ( preferenceId : string ) : Promise < void > {
215+ await this . activate ( ) ;
216+ const viewElement = await this . viewElement ( ) ;
217+ await viewElement ?. waitForSelector ( `${ this . getPreferenceGutterSelector ( preferenceId ) } ${ this . modificationIndicator } ` , { timeout : this . customTimeout } ) ;
218+ }
219+
220+ async waitForUnmodified ( preferenceId : string ) : Promise < void > {
221+ await this . activate ( ) ;
222+ const viewElement = await this . viewElement ( ) ;
223+ await viewElement ?. waitForSelector ( `${ this . getPreferenceGutterSelector ( preferenceId ) } ${ this . modificationIndicator } ` , { state : 'detached' , timeout : this . customTimeout } ) ;
224+ }
225+
226+ private getPreferenceGutterSelector ( preferenceId : string ) : string {
227+ return `${ this . getPreferenceSelector ( preferenceId ) } .pref-context-gutter` ;
228+ }
226229}
0 commit comments