blob: 49dad9bb312c409eaa6cdd372b97009ab5162b40 [file] [log] [blame]
/*
* Copyright (C) 2015 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.tools.idea.tests.gui.gradle;
import com.android.SdkConstants;
import com.android.tools.idea.tests.gui.framework.BelongsToTestGroups;
import com.android.tools.idea.tests.gui.framework.GuiTestCase;
import com.android.tools.idea.tests.gui.framework.IdeGuiTest;
import com.android.tools.idea.tests.gui.framework.IdeGuiTestSetup;
import com.android.tools.idea.tests.gui.framework.fixture.EditorFixture;
import com.android.tools.idea.tests.gui.framework.fixture.EditorNotificationPanelFixture;
import com.android.tools.idea.tests.gui.framework.fixture.IdeFrameFixture;
import com.intellij.ide.util.PropertiesComponent;
import com.intellij.openapi.projectRoots.Sdk;
import com.intellij.openapi.projectRoots.SdkModificator;
import com.intellij.openapi.roots.OrderRootType;
import com.intellij.openapi.vfs.VirtualFile;
import org.fest.swing.fixture.DialogFixture;
import org.fest.swing.fixture.JButtonFixture;
import org.fest.swing.timing.Condition;
import org.jetbrains.annotations.NotNull;
import org.junit.Before;
import org.junit.Test;
import java.io.File;
import java.io.IOException;
import static com.android.tools.idea.tests.gui.framework.GuiTests.SHORT_TIMEOUT;
import static com.android.tools.idea.tests.gui.framework.GuiTests.skip;
import static com.android.tools.idea.tests.gui.framework.TestGroup.PROJECT_SUPPORT;
import static com.intellij.openapi.util.io.FileUtil.join;
import static com.intellij.openapi.util.io.FileUtil.rename;
import static com.intellij.openapi.util.io.FileUtilRt.delete;
import static org.fest.assertions.Assertions.assertThat;
import static org.fest.swing.core.matcher.DialogMatcher.withTitle;
import static org.fest.swing.core.matcher.JButtonMatcher.withText;
import static org.fest.swing.finder.WindowFinder.findDialog;
import static org.fest.swing.timing.Pause.pause;
import static org.jetbrains.android.sdk.AndroidSdkUtils.*;
import static org.junit.Assert.assertNotNull;
@BelongsToTestGroups({PROJECT_SUPPORT})
@IdeGuiTestSetup(skipSourceGenerationOnSync = true)
public class AndroidSdkSourceAttachTest extends GuiTestCase {
private static final String ANDROID_PLATFORM = "android-22";
// Sdk used for the simpleApplication project.
private Sdk mySdk;
private File mySdkSourcePath;
private File mySdkSourceTmpPath;
@Before
public void restoreAndroidSdkSource() throws IOException {
mySdk = findSuitableAndroidSdk(ANDROID_PLATFORM);
if (mySdk != null) {
String sdkHomePath = mySdk.getHomePath();
mySdkSourcePath = new File(sdkHomePath, join("sources", ANDROID_PLATFORM));
mySdkSourceTmpPath = new File(sdkHomePath, join("sources.tmp", ANDROID_PLATFORM)); // it can't be in 'sources' folder
if (!mySdkSourcePath.isDirectory() && mySdkSourceTmpPath.isDirectory()) {
rename(mySdkSourceTmpPath, mySdkSourcePath);
}
}
}
@Test @IdeGuiTest
public void testDownloadSdkSource() throws IOException {
if (mySdk == null) {
printPlatformNotFound();
skip("testDownloadSdkSource");
return;
}
if (mySdkSourcePath.isDirectory()) {
delete(mySdkSourceTmpPath);
rename(mySdkSourcePath, mySdkSourceTmpPath);
}
updateSdkSourceRoot(mySdk);
IdeFrameFixture projectFrame = importSimpleApplication();
final EditorFixture editor = projectFrame.getEditor();
final VirtualFile classFile = findActivityClassFile();
editor.open(classFile, EditorFixture.Tab.EDITOR);
acceptLegalNoticeIfNeeded();
// Download the source.
findNotificationPanel(projectFrame).performAction("Download");
DialogFixture downloadDialog = findDialog(withTitle("SDK Quickfix Installation")).withTimeout(SHORT_TIMEOUT.duration()).using(myRobot);
final JButtonFixture finish = downloadDialog.button(withText("Finish"));
// Wait until installation is finished. By then the "Finish" button will be enabled.
pause(new Condition("Android source is installed") {
@Override
public boolean test() {
return finish.isEnabled();
}
});
finish.click();
pause(new Condition("Source file is opened") {
@Override
public boolean test() {
return !classFile.equals(editor.getCurrentFile());
}
}, SHORT_TIMEOUT);
VirtualFile sourceFile = editor.getCurrentFile();
assertNotNull(sourceFile);
assertIsActivityJavaFile(sourceFile);
}
@Test @IdeGuiTest
public void testRefreshSdkSource() throws IOException {
if (mySdk == null) {
printPlatformNotFound();
skip("testRefreshSdkSource");
return;
}
if (!mySdkSourcePath.isDirectory()) {
// Skip test if Sdk source is not installed.
System.out.println("Android Sdk Source for '" + mySdk.getName() + "' must be installed before running 'testRefreshSdkSource'");
skip("testRefreshSdkSource");
return;
}
clearLocalPkgInfo(mySdk);
SdkModificator sdkModificator = mySdk.getSdkModificator();
sdkModificator.removeRoots(OrderRootType.SOURCES);
sdkModificator.commitChanges();
IdeFrameFixture projectFrame = importSimpleApplication();
final EditorFixture editor = projectFrame.getEditor();
final VirtualFile classFile = findActivityClassFile();
editor.open(classFile, EditorFixture.Tab.EDITOR);
acceptLegalNoticeIfNeeded();
// Refresh the source.
findNotificationPanel(projectFrame).performAction("Refresh (if already downloaded)");
pause(new Condition("Source file is opened") {
@Override
public boolean test() {
return !classFile.equals(editor.getCurrentFile());
}
}, SHORT_TIMEOUT);
VirtualFile sourceFile = editor.getCurrentFile();
assertNotNull(sourceFile);
assertIsActivityJavaFile(sourceFile);
}
private static void printPlatformNotFound() {
System.out.println("SDK with platform '" + ANDROID_PLATFORM + "' not found");
}
private static void assertIsActivityJavaFile(@NotNull VirtualFile sourceFile) {
assertThat(sourceFile.getPath()).endsWith("android/app/Activity.java");
}
private void acceptLegalNoticeIfNeeded() {
if(!PropertiesComponent.getInstance().isTrueValue("decompiler.legal.notice.accepted")) {
DialogFixture acceptTermDialog = findDialog(withTitle("JetBrains Decompiler")).withTimeout(SHORT_TIMEOUT.duration()).using(myRobot);
acceptTermDialog.button(withText("Accept")).click();
}
}
@NotNull
private EditorNotificationPanelFixture findNotificationPanel(@NotNull IdeFrameFixture projectFrame) {
return projectFrame.requireEditorNotification(
"Sources for '" + mySdk.getName() + "' not found.");
}
@NotNull
private VirtualFile findActivityClassFile() {
VirtualFile jarRoot = null;
for (VirtualFile file : mySdk.getRootProvider().getFiles(OrderRootType.CLASSES)) {
if (file.getUrl().startsWith(SdkConstants.EXT_JAR)) {
jarRoot = file;
}
}
assertNotNull(jarRoot);
VirtualFile classFile = jarRoot.findFileByRelativePath("android/app/Activity.class");
assertNotNull(classFile);
return classFile;
}
}