Commit 4f3dbc06 authored by Romain Bioteau's avatar Romain Bioteau Committed by GitHub
Browse files

feat(deploy) update application preview (#1850)

* URL only open the app (if app and intro page is deployed)
* Deploy reuse the Deploy... handler selecting the dependency to deploy

Closes BST-442
parent 8a9d270a
......@@ -92,11 +92,13 @@ Export-Package: org.bonitasoft.studio.application,
org.bonitasoft.studio.application.actions,
org.bonitasoft.studio.application.actions.coolbar,
org.bonitasoft.studio.application.contribution,
org.bonitasoft.studio.application.handler,
org.bonitasoft.studio.application.i18n;
x-friends:="org.bonitasoft.studio.tests,
org.bonitasoft.studio.application.test,
org.bonitasoft.studio.diagram.test,
org.bonitasoft.studio.swtbot.framework",
org.bonitasoft.studio.swtbot.framework,
org.bonitasoft.studio.swtbot.framework.ex",
org.bonitasoft.studio.application.operation,
org.bonitasoft.studio.application.splash,
org.bonitasoft.studio.application.views,
......
......@@ -23,7 +23,9 @@ import java.net.MalformedURLException;
import java.net.URISyntaxException;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Collectors;
......@@ -46,6 +48,7 @@ import org.bonitasoft.studio.application.ui.control.RepositoryModelBuilder;
import org.bonitasoft.studio.application.ui.control.SelectArtifactToDeployPage;
import org.bonitasoft.studio.application.ui.control.model.Artifact;
import org.bonitasoft.studio.application.ui.control.model.BuildableArtifact;
import org.bonitasoft.studio.application.ui.control.model.FileStoreArtifact;
import org.bonitasoft.studio.application.ui.control.model.RepositoryModel;
import org.bonitasoft.studio.application.ui.control.model.TenantArtifact;
import org.bonitasoft.studio.common.jface.BonitaErrorDialog;
......@@ -53,6 +56,7 @@ import org.bonitasoft.studio.common.log.BonitaStudioLog;
import org.bonitasoft.studio.common.repository.Repository;
import org.bonitasoft.studio.common.repository.RepositoryAccessor;
import org.bonitasoft.studio.common.repository.model.DeployOptions;
import org.bonitasoft.studio.common.repository.model.IRepositoryFileStore;
import org.bonitasoft.studio.configuration.EnvironmentProviderFactory;
import org.bonitasoft.studio.engine.BOSEngineManager;
import org.bonitasoft.studio.engine.operation.GetApiSessionOperation;
......@@ -76,6 +80,7 @@ public class DeployArtifactsHandler {
private BuildProjectOperation buildOperation;
private RepositoryModel repositoryModel;
private List<IRepositoryFileStore> defaultSelection;
@Execute
public void deploy(@Named(IServiceConstants.ACTIVE_SHELL) Shell activeShell,
......@@ -88,6 +93,12 @@ public class DeployArtifactsHandler {
SelectArtifactToDeployPage page = new SelectArtifactToDeployPage(repositoryModel,
new EnvironmentProviderFactory().getEnvironmentProvider());
if(defaultSelection != null) {
page.setDefaultSelectedElements(defaultSelection.stream()
.map(fStore -> asArtifact(fStore))
.filter(Objects::nonNull)
.collect(Collectors.toSet()));
}
Optional<IStatus> result = createWizard(newWizard(), page,
repositoryAccessor,
Messages.selectArtifactToDeployTitle,
......@@ -97,6 +108,19 @@ public class DeployArtifactsHandler {
openStatusDialog(activeShell, result.get());
}
}
private Artifact asArtifact(IRepositoryFileStore fStore) {
return repositoryModel.getArtifacts().stream()
.filter(FileStoreArtifact.class::isInstance)
.map(FileStoreArtifact.class::cast)
.filter(artifact -> Objects.equals(artifact.getFileStore().getResource(),fStore.getResource()))
.findFirst()
.orElse(null);
}
public void setDefaultSelection(List<IRepositoryFileStore> defaultSelection) {
this.defaultSelection = defaultSelection;
}
protected IStatus deployArtifacts(RepositoryAccessor repositoryAccessor,
Collection<Artifact> artifactsToDeploy,
......
......@@ -119,13 +119,20 @@ public class SelectArtifactToDeployPage implements ControlSupplier {
public void loadSettings(IDialogSettings settings) {
IDialogSettings section = settings.getSection(repositoryModel.getName());
if (section != null && section.getArray(DEPLOY_DEFAULT_SELECTION) != null) {
defaultSelectedElements = fromStrings(section.getArray(DEPLOY_DEFAULT_SELECTION));
if(defaultSelectedElements == null || defaultSelectedElements.isEmpty()) {
defaultSelectedElements = fromStrings(section.getArray(DEPLOY_DEFAULT_SELECTION));
}
cleanBDM = section.getBoolean(CLEAN_BDM_DEFAULT_SELECTION);
validate = section.getBoolean(VALIDATE_DEFAULT_SELECTION);
}
environment = ConfigurationPlugin.getDefault().getPreferenceStore()
.getString(ConfigurationPreferenceConstants.DEFAULT_CONFIGURATION);
}
public void setDefaultSelectedElements(Set<Object> defaultSelectedElements) {
this.defaultSelectedElements = defaultSelectedElements;
}
@Override
public void saveSettings(IDialogSettings settings) {
......
......@@ -57,5 +57,9 @@ public class FileStoreArtifact implements Artifact {
public Object getParent() {
return parent;
}
public IRepositoryFileStore getFileStore(){
return fStore;
}
}
......@@ -102,10 +102,6 @@ public class WebPageRepositoryStore extends WebArtifactRepositoryStore<WebPageFi
.findFirst();
}
/*
* (non-Javadoc)
* @see org.bonitasoft.studio.common.repository.store.AbstractFolderRepositoryStore#getChild(java.lang.String)
*/
@Override
public WebPageFileStore getChild(String uuid, boolean force) {
IPath location = getResource().getLocation();
......
......@@ -27,9 +27,12 @@ Require-Bundle: org.bonitasoft.studio.common.repository;bundle-version="7.5.0",
org.bonitasoft.studio.actors,
org.bonitasoft.studio.engine,
org.bonitasoft.studio.application,
org.eclipse.core.expressions
org.eclipse.core.expressions,
org.bonitasoft.studio.designer;bundle-version="7.10.0",
org.eclipse.e4.core.contexts
Bundle-RequiredExecutionEnvironment: JavaSE-1.8
Import-Package: javax.activation;version="1.1.0",
javax.annotation;version="1.2.0",
javax.xml.bind;version="2.2.0",
org.bonitasoft.engine.api,
org.bonitasoft.engine.bpm,
......
<?xml version="1.0" encoding="ASCII"?>
<fragment:ModelFragments xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:commands="http://www.eclipse.org/ui/2010/UIModel/application/commands" xmlns:fragment="http://www.eclipse.org/ui/2010/UIModel/fragment" xmi:id="_jKdtYNKdEeaEE_Umqe0dXA">
<fragment:ModelFragments xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:application="http://www.eclipse.org/ui/2010/UIModel/application" xmlns:commands="http://www.eclipse.org/ui/2010/UIModel/application/commands" xmlns:fragment="http://www.eclipse.org/ui/2010/UIModel/fragment" xmi:id="_jKdtYNKdEeaEE_Umqe0dXA">
<fragments xsi:type="fragment:StringModelFragment" xmi:id="_tWbyINKdEeaEE_Umqe0dXA" featurename="commands" parentElementId="org.eclipse.e4.legacy.ide.application">
<elements xsi:type="commands:Command" xmi:id="_0n838NKdEeaEE_Umqe0dXA" elementId="org.bonitasoft.studio.la.new.command" commandName="%newApplication"/>
<elements xsi:type="commands:Command" xmi:id="_dHtcoP3SEeanhv23kWy-6w" elementId="org.bonitasoft.studio.la.open.command" commandName="%openApplication"/>
......@@ -22,4 +22,7 @@
<elements xsi:type="commands:Handler" xmi:id="_JVGowM6fEee2rb_HhIZr1w" elementId="org.bonitasoft.studio.la.handler.deployapplication" contributionURI="bundleclass://org.bonitasoft.studio.la/org.bonitasoft.studio.la.application.handler.DeployApplicationHandler" command="_pL3WsPnPEea-3Os5NcIV0g"/>
<elements xsi:type="commands:Handler" xmi:id="_NaDQgPyNEeicTeF1RHOGZw" elementId="org.bonitasoft.studio.la.findOpenedEditor.handler" contributionURI="bundleclass://org.bonitasoft.studio.la/org.bonitasoft.studio.la.application.handler.FindOpenedEditorHandler" command="_kyZscPyMEeicTeF1RHOGZw"/>
</fragments>
<fragments xsi:type="fragment:StringModelFragment" xmi:id="_FB5hgMmbEemR19YdSwyeIw" featurename="addons" parentElementId="org.eclipse.e4.legacy.ide.application">
<elements xsi:type="application:Addon" xmi:id="_Kl2SQMmbEemR19YdSwyeIw" elementId="org.bonitasoft.studio.la.dependency.resolver.addon" contributionURI="bundleclass://org.bonitasoft.studio.la/org.bonitasoft.studio.la.application.core.DefaultApplicationDependencyResolver"/>
</fragments>
</fragment:ModelFragments>
/**
* Copyright (C) 2019 Bonitasoft S.A.
* Bonitasoft, 32 rue Gustave Eiffel - 38000 Grenoble
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2.0 of the License, or
* (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.bonitasoft.studio.la.application.core;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import javax.annotation.PostConstruct;
import org.bonitasoft.engine.business.application.xml.ApplicationNode;
import org.bonitasoft.engine.business.application.xml.ApplicationNodeContainer;
import org.bonitasoft.engine.business.application.xml.ApplicationPageNode;
import org.bonitasoft.studio.common.log.BonitaStudioLog;
import org.bonitasoft.studio.common.repository.model.IRepositoryFileStore;
import org.bonitasoft.studio.common.repository.model.ReadFileStoreException;
import org.bonitasoft.studio.designer.core.repository.WebPageRepositoryStore;
import org.bonitasoft.studio.la.application.repository.ApplicationFileStore;
import org.eclipse.e4.core.contexts.IEclipseContext;
public class DefaultApplicationDependencyResolver implements DependencyResolver<ApplicationFileStore> {
@PostConstruct
public void inject(IEclipseContext context) {
if(!context.containsKey(DependencyResolver.class)) {
context.set(DependencyResolver.class, this);
}
}
@Override
public List<IRepositoryFileStore> findDependencies(ApplicationFileStore fStore) {
List<IRepositoryFileStore> result = new ArrayList<>();
try {
WebPageRepositoryStore webStore = fStore.getRepository().getRepositoryStore(WebPageRepositoryStore.class);
ApplicationNodeContainer applicationNodeContainer = fStore.getContent();
//Application Pages
applicationNodeContainer
.getApplications()
.stream()
.map(ApplicationNode::getApplicationPages)
.flatMap(Collection::stream)
.map(ApplicationPageNode::getCustomPage)
.distinct()
.map(customPage -> webStore.findByPageId(customPage).orElse(null))
.filter(Objects::nonNull)
.forEach(result::add);
//Layout
applicationNodeContainer
.getApplications()
.stream()
.map(ApplicationNode::getLayout)
.distinct()
.map(customPage -> webStore.findByPageId(customPage).orElse(null))
.filter(Objects::nonNull)
.forEach(result::add);
return result;
} catch (ReadFileStoreException e) {
BonitaStudioLog.error(e);
}
return Collections.emptyList();
}
}
/**
* Copyright (C) 2019 Bonitasoft S.A.
* Bonitasoft, 32 rue Gustave Eiffel - 38000 Grenoble
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2.0 of the License, or
* (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.bonitasoft.studio.la.application.core;
import java.util.List;
import org.bonitasoft.studio.common.repository.model.IRepositoryFileStore;
public interface DependencyResolver<T extends IRepositoryFileStore> {
List<IRepositoryFileStore> findDependencies(T fStore);
}
......@@ -14,20 +14,25 @@
*/
package org.bonitasoft.studio.la.application.handler;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import javax.inject.Named;
import org.bonitasoft.engine.business.application.xml.ApplicationNodeContainer;
import org.bonitasoft.studio.application.handler.DeployArtifactsHandler;
import org.bonitasoft.studio.common.log.BonitaStudioLog;
import org.bonitasoft.studio.common.repository.RepositoryAccessor;
import org.bonitasoft.studio.common.repository.model.ReadFileStoreException;
import org.bonitasoft.studio.common.repository.model.IRepositoryFileStore;
import org.bonitasoft.studio.la.application.core.DependencyResolver;
import org.bonitasoft.studio.la.application.core.DeployApplicationAction;
import org.bonitasoft.studio.la.application.repository.ApplicationFileStore;
import org.bonitasoft.studio.la.application.repository.ApplicationRepositoryStore;
import org.eclipse.e4.core.di.annotations.CanExecute;
import org.eclipse.e4.core.di.annotations.Execute;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.PlatformUI;
public class DeployApplicationHandler {
......@@ -35,33 +40,37 @@ public class DeployApplicationHandler {
@Execute
public void execute(RepositoryAccessor repositoryAccessor, Shell shell,
@org.eclipse.e4.core.di.annotations.Optional @Named(APPLICATION_TO_DEPLOY_PARAMETER) String application) {
deploy(repositoryAccessor, shell, new DeployApplicationAction(repositoryAccessor), application);
@org.eclipse.e4.core.di.annotations.Optional @Named(APPLICATION_TO_DEPLOY_PARAMETER) String application,
DependencyResolver<ApplicationFileStore> dependencyResolver) {
deploy(repositoryAccessor, shell, new DeployApplicationAction(repositoryAccessor), application, dependencyResolver);
}
protected void deploy(RepositoryAccessor repositoryAccessor, Shell shell, DeployApplicationAction action,
String application) {
Optional<ApplicationNodeContainer> applicationToDeploy = findApplicationToDeploy(repositoryAccessor, application);
if (applicationToDeploy.isPresent()) {
action.deployApplicationNodeContainer(shell, applicationToDeploy.get(),
new String[] { IDialogConstants.OK_LABEL });
String application, DependencyResolver<ApplicationFileStore> dependencyResolver) {
Optional<ApplicationFileStore> applicationFileStore = findApplicationToDeploy(repositoryAccessor,
application);
if (applicationFileStore.isPresent()) {
DeployArtifactsHandler deployArtifactsHandler = new DeployArtifactsHandler();
List<IRepositoryFileStore> defaultSelection = new ArrayList<>();
ApplicationFileStore fileStore = applicationFileStore.get();
defaultSelection.add(fileStore);
defaultSelection.addAll(dependencyResolver.findDependencies(fileStore));
deployArtifactsHandler.setDefaultSelection(defaultSelection);
try {
deployArtifactsHandler.deploy(shell, repositoryAccessor, PlatformUI.getWorkbench().getProgressService());
} catch (InvocationTargetException | InterruptedException e) {
BonitaStudioLog.error(e);
}
} else {
action.selectAndDeploy(shell);
}
}
protected Optional<ApplicationNodeContainer> findApplicationToDeploy(RepositoryAccessor repositoryAccessor,
protected Optional<ApplicationFileStore> findApplicationToDeploy(RepositoryAccessor repositoryAccessor,
String application) {
if (application != null) {
ApplicationFileStore fileStore = repositoryAccessor.getRepositoryStore(ApplicationRepositoryStore.class)
.getChild(application, true);
try {
return fileStore == null
? Optional.empty()
: Optional.of(fileStore.getContent());
} catch (ReadFileStoreException e) {
throw new RuntimeException(e);
}
if(application != null) {
return Optional.of(repositoryAccessor.getRepositoryStore(ApplicationRepositoryStore.class)
.getChild(application, true));
}
return Optional.empty();
}
......
......@@ -19,15 +19,24 @@ import static com.google.common.base.Preconditions.checkArgument;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Stream;
import javax.xml.bind.JAXBException;
import org.bonitasoft.engine.business.application.ApplicationMenu;
import org.bonitasoft.engine.business.application.exporter.ApplicationNodeContainerConverter;
import org.bonitasoft.engine.business.application.xml.ApplicationMenuNode;
import org.bonitasoft.engine.business.application.xml.ApplicationNode;
import org.bonitasoft.engine.business.application.xml.ApplicationNodeContainer;
import org.bonitasoft.engine.business.application.xml.ApplicationPageNode;
import org.bonitasoft.studio.common.log.BonitaStudioLog;
import org.bonitasoft.studio.common.repository.Repository;
import org.bonitasoft.studio.common.repository.filestore.AbstractFileStore;
......@@ -37,6 +46,7 @@ import org.bonitasoft.studio.common.repository.model.IRenamable;
import org.bonitasoft.studio.common.repository.model.IRepositoryFileStore;
import org.bonitasoft.studio.common.repository.model.IRepositoryStore;
import org.bonitasoft.studio.common.repository.model.ReadFileStoreException;
import org.bonitasoft.studio.designer.core.repository.WebPageRepositoryStore;
import org.bonitasoft.studio.ui.i18n.Messages;
import org.bonitasoft.studio.ui.validator.ExtensionSupported;
import org.bonitasoft.studio.ui.validator.FileNameValidator;
......
......@@ -43,9 +43,6 @@ import org.eclipse.swt.SWT;
import org.eclipse.swt.events.TraverseEvent;
import org.eclipse.swt.events.TraverseListener;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
......@@ -178,8 +175,9 @@ public class TextWidget extends EditableControlWidget {
modelObservable,
targetToModelStrategy,
modelToTargetStrategy);
validator.ifPresent(v -> control.bindValidator(ctx, delay.map(time -> control.observeText(time, SWT.Modify))
.orElse(control.observeText(SWT.Modify)),
validator.ifPresent(v -> control.bindValidator(ctx,
delay.map(time -> control.observeText(time, SWT.Modify))
.orElse(control.observeText(SWT.Modify)),
modelObservable,
v));
}
......@@ -224,8 +222,8 @@ public class TextWidget extends EditableControlWidget {
@Override
protected int horizontalSpacing() {
if(labelAbove && transactionalEdit) {
return 1 ;
if (labelAbove && transactionalEdit) {
return 1;
}
return super.horizontalSpacing();
}
......@@ -279,10 +277,6 @@ public class TextWidget extends EditableControlWidget {
return this;
}
/*
* (non-Javadoc)
* @see org.bonitasoft.studio.ui.widget.EditableControlWidget#selectedBorderColor(org.eclipse.swt.widgets.Control)
*/
@Override
protected Color selectedBorderColor(Control container) {
return editing ? editingColor : super.selectedBorderColor(container);
......@@ -325,21 +319,6 @@ public class TextWidget extends EditableControlWidget {
text.addListener(SWT.FocusIn, event -> redraw(textContainer));
text.addListener(SWT.FocusOut, event -> redraw(textContainer));
text.addListener(SWT.Paint, event -> {
if (!text.isEnabled()) {
final GC gc = event.gc;
final String textString = text.getText();
final Rectangle bounds = text.getBounds();
final Point caretLocation = text.getCaretLocation();
gc.setBackground(text.getDisplay().getSystemColor(SWT.COLOR_WIDGET_BACKGROUND));
gc.setForeground(text.getDisplay().getSystemColor(SWT.COLOR_DARK_GRAY));
gc.fillRectangle(0, 0, bounds.width, bounds.height);
gc.drawText(textString, bounds.x + 1, caretLocation.y);
}
});
if (transactionalEdit) {
final ToolBar toolBar = new ToolBar(this, SWT.INHERIT_DEFAULT | SWT.NO_FOCUS);
......@@ -377,7 +356,7 @@ public class TextWidget extends EditableControlWidget {
private void openProposalPopup(CustomContentProposalAdapter proposalAdapter) {
text.getDisplay().asyncExec(() -> {
if (!text.isDisposed() && proposalAdapter != null && !proposalAdapter.isProposalPopupOpen()) {
if(text.getText() == null || text.getText().isEmpty()) {
if (text.getText() == null || text.getText().isEmpty()) {
proposalAdapter.openProposalPopup();
}
}
......@@ -394,7 +373,8 @@ public class TextWidget extends EditableControlWidget {
protected void createEditItem(final ToolBar toolBar) {
final ToolItem editButton = new ToolItem(toolBar, SWT.FLAT);
editButton.setData(SWTBotConstants.SWTBOT_WIDGET_ID_KEY, "org.bonitasoft.studio.ui.widget.textWidget.editButton");
editButton.setData(SWTBotConstants.SWTBOT_WIDGET_ID_KEY,
"org.bonitasoft.studio.ui.widget.textWidget.editButton");
editButton.setImage(ImageDescriptor.createFromFile(TextWidget.class, "edit.png").createImage());
editButton.addListener(SWT.Dispose, event -> editButton.getImage().dispose());
editButton.setToolTipText(Messages.edit);
......@@ -416,7 +396,8 @@ public class TextWidget extends EditableControlWidget {
cancelButton.addListener(SWT.Dispose, event -> cancelButton.getImage().dispose());
okButton = new ToolItem(toolBar, SWT.FLAT);
okButton.setData(SWTBotConstants.SWTBOT_WIDGET_ID_KEY, "org.bonitasoft.studio.ui.widget.textWidget.validateEdit");
okButton.setData(SWTBotConstants.SWTBOT_WIDGET_ID_KEY,
"org.bonitasoft.studio.ui.widget.textWidget.validateEdit");
okButton.setImage(ImageDescriptor.createFromFile(TextWidget.class, "checked.png").createImage());
okButton.setToolTipText(Messages.applyEdit);
okButton.addListener(SWT.Selection, okListener(toolBar));
......
......@@ -57,9 +57,12 @@ public class LivingApplicationProjectExplorerBot extends ProjectExplorerBot {
public void deployApplication(String application) {
clickOnContextualMenu(getApplicationTreeItem(application), "Deploy");
bot.waitUntil(Conditions.shellIsActive(org.bonitasoft.studio.la.i18n.Messages.deployDoneTitle));
bot.waitUntil(Conditions.shellIsActive(org.bonitasoft.studio.application.i18n.Messages.selectArtifactToDeployTitle));
SWTBotShell activeShell = bot.activeShell();
bot.button(IDialogConstants.OK_LABEL).click();
bot.button(org.bonitasoft.studio.application.i18n.Messages.deploy).click();
bot.waitUntil(Conditions.shellIsActive(org.bonitasoft.studio.application.i18n.Messages.deployStatus));
activeShell = bot.activeShell();
bot.button(IDialogConstants.CLOSE_LABEL).click();
bot.waitUntil(Conditions.shellCloses(activeShell));
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment